mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Merge branch 'master' into Jeffail-master
Conflicts: core/DHT.c
This commit is contained in:
commit
b9176974a8
@ -21,12 +21,15 @@ before_script:
|
||||
- cd ..
|
||||
# creating librarys' links and updating cache
|
||||
- sudo ldconfig
|
||||
|
||||
# installing sphinx, needed for documentation
|
||||
- sudo apt-get install python-sphinx
|
||||
|
||||
script:
|
||||
- mkdir build && cd build
|
||||
- cmake ..
|
||||
- make -j3
|
||||
# build docs separately
|
||||
- make docs
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
@ -48,3 +48,4 @@ cmake_policy(SET CMP0011 NEW)
|
||||
add_subdirectory(core)
|
||||
add_subdirectory(testing)
|
||||
add_subdirectory(other)
|
||||
add_subdirectory(docs)
|
||||
|
11
INSTALL.md
11
INSTALL.md
@ -6,7 +6,6 @@
|
||||
- [Homebrew](#homebrew)
|
||||
- [Non-Homebrew](#non-homebrew)
|
||||
- [Windows](#windows)
|
||||
- [Usage](#usage)
|
||||
|
||||
<a name="installation" />
|
||||
##Installation
|
||||
@ -32,11 +31,14 @@ sudo checkinstall --install --pkgname libsodium --pkgversion 0.4.2 --nodoc
|
||||
sudo ldconfig
|
||||
```
|
||||
|
||||
Then clone this repo and run:
|
||||
Then clone this repo and generate makefile:
|
||||
```bash
|
||||
git clone git://github.com/irungentoo/ProjectTox-Core.git
|
||||
cd ProjectTox-Core
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
```
|
||||
Note that you should call cmake on the root [`CMakeLists.txt`](/CMakeLists.txt) file only.
|
||||
|
||||
Then you can build any of the [`/testing`](/testing) and [`/other`](/other) that are currently supported on your platform by running:
|
||||
```bash
|
||||
@ -102,6 +104,7 @@ Navigate in `cmd` to this repo and run:
|
||||
mkdir build && cd build
|
||||
cmake -G "MinGW Makefiles" ..
|
||||
```
|
||||
Note that you should call cmake on the root [`CMakeLists.txt`](/CMakeLists.txt) file only.
|
||||
|
||||
Then you can build any of the [`/testing`](/testing) and [`/other`](/other) that are currently supported on your platform by running:
|
||||
```cmd
|
||||
@ -117,7 +120,3 @@ Or you could just build everything that is supported on your platform by running
|
||||
mingw32-make
|
||||
```
|
||||
|
||||
<a name="usage" />
|
||||
## Usage
|
||||
|
||||
- [Start Guide](start_guide.md)
|
||||
|
@ -13,7 +13,7 @@ With the rise of governmental monitoring programs, Tox aims to be an easy to use
|
||||
|
||||
**How to build Tox on Linux**: [YouTube video](http://www.youtube.com/watch?v=M4WXE4VKmyg)<br />
|
||||
**How to use Tox on Windows**: [YouTube video](http://www.youtube.com/watch?v=qg_j_sDb6WQ)<br />
|
||||
**For Mac OSX read INSTALL.md**
|
||||
**For Mac OSX read** [INSTALL.md](INSTALL.md)
|
||||
|
||||
### Objectives:
|
||||
|
||||
@ -35,13 +35,13 @@ Keep everything really simple.
|
||||
- [ ] Streaming media
|
||||
- [ ] ???
|
||||
|
||||
For further information, check our [To-do list](https://github.com/irungentoo/ProjectTox-Core/wiki/TODO)
|
||||
For further information, check our [To-do list](http://wiki.tox.im/index.php/TODO)
|
||||
|
||||
### Why are you doing this? There are already a bunch of free skype alternatives.
|
||||
The goal of this project is to create a configuration-free P2P skype
|
||||
replacement. Configuration-free means that the user will simply have to open the program and
|
||||
without any account configuration will be capable of adding people to his
|
||||
friends list and start conversing with them. There are many so called skype replacements and all of them are either hard to
|
||||
friends list and start conversing with them. There are many so-called skype replacements and all of them are either hard to
|
||||
configure for the normal user or suffer from being way too centralized.
|
||||
|
||||
### Documentation:
|
||||
|
@ -1,9 +0,0 @@
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" => Text, tab and indent related
|
||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
" Use spaces instead of tabs
|
||||
set expandtab
|
||||
|
||||
" 1 tab == 4 spaces
|
||||
set shiftwidth=4
|
||||
set tabstop=4
|
16
cmake/FindSphinx.cmake
Normal file
16
cmake/FindSphinx.cmake
Normal file
@ -0,0 +1,16 @@
|
||||
find_program(SPHINX_EXECUTABLE NAMES sphinx-build
|
||||
HINTS
|
||||
$ENV{SPHINX_DIR}
|
||||
PATH_SUFFIXES bin
|
||||
DOC "Sphinx documentation generator"
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package_handle_standard_args(Sphinx DEFAULT_MSG
|
||||
SPHINX_EXECUTABLE
|
||||
)
|
||||
|
||||
mark_as_advanced(
|
||||
SPHINX_EXECUTABLE
|
||||
)
|
51
core/DHT.c
51
core/DHT.c
@ -85,7 +85,7 @@ typedef struct {
|
||||
uint8_t hole_punching;
|
||||
uint32_t punching_index;
|
||||
uint32_t punching_timestamp;
|
||||
uint32_t recvNATping_timestamp;
|
||||
int64_t recvNATping_timestamp;
|
||||
uint64_t NATping_id;
|
||||
uint32_t NATping_timestamp;
|
||||
} Friend;
|
||||
@ -98,7 +98,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
IP_Port ip_port;
|
||||
uint64_t ping_id;
|
||||
uint32_t timestamp;
|
||||
int64_t timestamp;
|
||||
} Pinged;
|
||||
|
||||
/*----------------------------------------------------------------------------------*/
|
||||
@ -145,7 +145,8 @@ int id_closest(uint8_t * client_id, uint8_t * client_id1, uint8_t * client_id2)
|
||||
*/
|
||||
int client_in_list(Client_data * list, uint32_t length, uint8_t * client_id, IP_Port ip_port)
|
||||
{
|
||||
uint32_t i, temp_time = unix_time();
|
||||
uint32_t i;
|
||||
int64_t temp_time = unix_time();
|
||||
|
||||
for(i = 0; i < length; ++i) {
|
||||
/*If ip_port is assigned to a different client_id replace it*/
|
||||
@ -197,7 +198,8 @@ static int friend_number(uint8_t * client_id)
|
||||
*/
|
||||
int get_close_nodes(uint8_t * client_id, Node_format * nodes_list)
|
||||
{
|
||||
uint32_t i, j, k, temp_time = unix_time();
|
||||
uint32_t i, j, k;
|
||||
int64_t temp_time = unix_time();
|
||||
int num_nodes = 0, closest, tout, inlist;
|
||||
|
||||
for (i = 0; i < LCLIENT_LIST; ++i) {
|
||||
@ -283,7 +285,7 @@ int replace_bad( Client_data * list,
|
||||
IP_Port ip_port )
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t temp_time = unix_time();
|
||||
int64_t temp_time = unix_time();
|
||||
for(i = 0; i < length; ++i) {
|
||||
/* if node is bad */
|
||||
if(list[i].timestamp + BAD_NODE_TIMEOUT < temp_time) {
|
||||
@ -308,7 +310,7 @@ int replace_good( Client_data * list,
|
||||
uint8_t * comp_client_id )
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t temp_time = unix_time();
|
||||
int64_t temp_time = unix_time();
|
||||
|
||||
for(i = 0; i < length; ++i)
|
||||
if(id_closest(comp_client_id, list[i].client_id, client_id) == 2) {
|
||||
@ -371,7 +373,8 @@ void addto_lists(IP_Port ip_port, uint8_t * client_id)
|
||||
*/
|
||||
void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient_id)
|
||||
{
|
||||
uint32_t i, j, temp_time = unix_time();
|
||||
uint32_t i, j;
|
||||
int64_t temp_time = unix_time();
|
||||
|
||||
if (memcmp(client_id, self_public_key, CLIENT_ID_SIZE) == 0) {
|
||||
for (i = 0; i < LCLIENT_LIST; ++i) {
|
||||
@ -411,8 +414,9 @@ void returnedip_ports(IP_Port ip_port, uint8_t * client_id, uint8_t * nodeclient
|
||||
*/
|
||||
int is_pinging(IP_Port ip_port, uint64_t ping_id)
|
||||
{
|
||||
uint32_t i, temp_time = unix_time();
|
||||
uint32_t i;
|
||||
uint8_t pinging;
|
||||
int64_t temp_time = unix_time();
|
||||
|
||||
for (i = 0; i < LPING_ARRAY; ++i ) {
|
||||
if ((pings[i].timestamp + PING_TIMEOUT) > temp_time) {
|
||||
@ -434,8 +438,9 @@ int is_pinging(IP_Port ip_port, uint64_t ping_id)
|
||||
/* Same as last function but for get_node requests. */
|
||||
int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
|
||||
{
|
||||
uint32_t i, temp_time = unix_time();
|
||||
uint32_t i;
|
||||
uint8_t pinging;
|
||||
int64_t temp_time = unix_time();
|
||||
|
||||
for(i = 0; i < LSEND_NODES_ARRAY; ++i ) {
|
||||
if((send_nodes[i].timestamp + PING_TIMEOUT) > temp_time) {
|
||||
@ -462,8 +467,10 @@ int is_gettingnodes(IP_Port ip_port, uint64_t ping_id)
|
||||
*/
|
||||
uint64_t add_pinging(IP_Port ip_port)
|
||||
{
|
||||
uint32_t i, j, temp_time = unix_time();
|
||||
uint32_t i, j;
|
||||
uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
|
||||
int64_t temp_time = unix_time();
|
||||
|
||||
|
||||
for(i = 0; i < PING_TIMEOUT; ++i ) {
|
||||
for(j = 0; j < LPING_ARRAY; ++j ) {
|
||||
@ -484,7 +491,7 @@ uint64_t add_gettingnodes(IP_Port ip_port)
|
||||
{
|
||||
uint32_t i, j;
|
||||
uint64_t ping_id = ((uint64_t)random_int() << 32) + random_int();
|
||||
uint32_t temp_time = unix_time();
|
||||
int64_t temp_time = unix_time();
|
||||
|
||||
for(i = 0; i < PING_TIMEOUT; ++i ) {
|
||||
for(j = 0; j < LSEND_NODES_ARRAY; ++j ) {
|
||||
@ -823,7 +830,8 @@ int DHT_delfriend(uint8_t * client_id)
|
||||
/* TODO: Optimize this. */
|
||||
IP_Port DHT_getfriendip(uint8_t * client_id)
|
||||
{
|
||||
uint32_t i, j, temp_time = unix_time();
|
||||
uint32_t i, j;
|
||||
int64_t temp_time = unix_time();
|
||||
IP_Port empty = {{{0}}, 0};
|
||||
|
||||
for (i = 0; i < num_friends; ++i) {
|
||||
@ -849,7 +857,7 @@ IP_Port DHT_getfriendip(uint8_t * client_id)
|
||||
void doDHTFriends()
|
||||
{
|
||||
uint32_t i, j;
|
||||
uint32_t temp_time = unix_time();
|
||||
int64_t temp_time = unix_time();
|
||||
uint32_t rand_node;
|
||||
uint32_t index[MAX_FRIEND_CLIENTS];
|
||||
|
||||
@ -888,7 +896,7 @@ static uint32_t close_lastgetnodes;
|
||||
void doClose()
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t temp_time = unix_time();
|
||||
int64_t temp_time = unix_time();
|
||||
uint32_t num_nodes = 0;
|
||||
uint32_t rand_node;
|
||||
uint32_t index[LCLIENT_LIST];
|
||||
@ -945,8 +953,9 @@ int route_packet(uint8_t * client_id, uint8_t * packet, uint32_t length)
|
||||
static int friend_iplist(IP_Port * ip_portlist, uint16_t friend_num)
|
||||
{
|
||||
int num_ips = 0;
|
||||
uint32_t i, temp_time = unix_time();
|
||||
|
||||
uint32_t i;
|
||||
int64_t temp_time = unix_time();
|
||||
|
||||
if (friend_num >= num_friends)
|
||||
return -1;
|
||||
|
||||
@ -979,7 +988,8 @@ int route_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
|
||||
if (num == -1)
|
||||
return 0;
|
||||
|
||||
uint32_t i, sent = 0, temp_time = unix_time();
|
||||
uint32_t i, sent = 0;
|
||||
int64_t temp_time = unix_time();
|
||||
Friend * friend = &friends_list[num];
|
||||
Client_data * client;
|
||||
|
||||
@ -1012,6 +1022,7 @@ int routeone_tofriend(uint8_t * friend_id, uint8_t * packet, uint32_t length)
|
||||
IP_Port ip_list[MAX_FRIEND_CLIENTS];
|
||||
int n = 0;
|
||||
uint32_t i, temp_time = unix_time();
|
||||
int64_t temp_time = unix_time();
|
||||
|
||||
for (i = 0; i < MAX_FRIEND_CLIENTS; ++i) {
|
||||
client = &friend->client_list[i];
|
||||
@ -1184,7 +1195,8 @@ static void punch_holes(IP ip, uint16_t * port_list, uint16_t numports, uint16_t
|
||||
|
||||
static void doNAT()
|
||||
{
|
||||
uint32_t i, temp_time = unix_time();
|
||||
uint32_t i;
|
||||
int64_t temp_time = unix_time();
|
||||
|
||||
for (i = 0; i < num_friends; ++i) {
|
||||
IP_Port ip_list[MAX_FRIEND_CLIENTS];
|
||||
@ -1279,7 +1291,7 @@ int DHT_load(uint8_t * data, uint32_t size)
|
||||
|
||||
uint32_t i, j;
|
||||
uint16_t temp;
|
||||
/* uint32_t temp_time = unix_time(); */
|
||||
/* int64_t temp_time = unix_time(); */
|
||||
|
||||
Client_data * client;
|
||||
|
||||
@ -1314,6 +1326,7 @@ int DHT_load(uint8_t * data, uint32_t size)
|
||||
int DHT_isconnected()
|
||||
{
|
||||
uint32_t i, temp_time = unix_time();
|
||||
int64_t temp_time = unix_time();
|
||||
|
||||
for(i = 0; i < LCLIENT_LIST; ++i) {
|
||||
if(close_clientlist[i].timestamp + BAD_NODE_TIMEOUT > temp_time)
|
||||
|
@ -31,7 +31,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Current time, unix format */
|
||||
#define unix_time() ((uint32_t)time(NULL))
|
||||
#define unix_time() ((int64_t)time(NULL))
|
||||
|
||||
/* size of the client_id in bytes */
|
||||
#define CLIENT_ID_SIZE crypto_box_PUBLICKEYBYTES
|
||||
|
@ -23,13 +23,70 @@
|
||||
|
||||
#include "LAN_discovery.h"
|
||||
|
||||
#define MAX_INTERFACES 16
|
||||
|
||||
/*Return the broadcast ip
|
||||
TODO: make it return the real one, not the 255.255.255.255 one.*/
|
||||
#ifdef __linux
|
||||
/* get the first working broadcast address that's not from "lo"
|
||||
* returns higher than 0 on success
|
||||
* returns 0 on error */
|
||||
uint32_t get_broadcast(void)
|
||||
{
|
||||
/* not sure how many platforms this will
|
||||
* run on, so it's wrapped in __linux for now */
|
||||
struct sockaddr_in *sock_holder = NULL;
|
||||
struct ifreq i_faces[MAX_INTERFACES];
|
||||
struct ifconf ifconf;
|
||||
int count = 0;
|
||||
int sock = 0;
|
||||
int i = 0;
|
||||
|
||||
/* configure ifconf for the ioctl call */
|
||||
if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
perror("[!] get_broadcast: socket() error");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(i_faces, 0, sizeof(struct ifreq) * MAX_INTERFACES);
|
||||
|
||||
ifconf.ifc_buf = (char *)i_faces;
|
||||
ifconf.ifc_len = sizeof(i_faces);
|
||||
count = ifconf.ifc_len / sizeof(struct ifreq);
|
||||
if(ioctl(sock, SIOCGIFCONF, &ifconf) < 0) {
|
||||
perror("get_broadcast: ioctl() error");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < count; i++) {
|
||||
/* skip the loopback interface, as it's useless */
|
||||
if(strcmp(i_faces[i].ifr_name, "lo") != 0) {
|
||||
if(ioctl(sock, SIOCGIFBRDADDR, &i_faces[i]) < 0) {
|
||||
perror("[!] get_broadcast: ioctl error");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* just to clarify where we're getting the values from */
|
||||
sock_holder = (struct sockaddr_in *)&i_faces[i].ifr_broadaddr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
close(sock);
|
||||
|
||||
return sock_holder->sin_addr.s_addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return the broadcast ip */
|
||||
IP broadcast_ip()
|
||||
{
|
||||
IP ip;
|
||||
#ifdef __linux
|
||||
ip.i = get_broadcast();
|
||||
if(ip.i == 0)
|
||||
/* error errored, but try anyway? */
|
||||
ip.i = ~0;
|
||||
#else
|
||||
ip.i = ~0;
|
||||
#endif
|
||||
return ip;
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,13 @@
|
||||
|
||||
#include "DHT.h"
|
||||
|
||||
/* used for get_broadcast() */
|
||||
#ifdef __linux
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/netdevice.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -21,67 +21,95 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* TODO: clean this file a bit.
|
||||
There are a couple of useless variables to get rid of. */
|
||||
/*
|
||||
* TODO: clean this file a bit.
|
||||
* There are a couple of useless variables to get rid of.
|
||||
*/
|
||||
|
||||
#include "Lossless_UDP.h"
|
||||
|
||||
/* maximum data packets in sent and receive queues. */
|
||||
#define MAX_QUEUE_NUM 16
|
||||
|
||||
/* maximum length of the data in the data packets */
|
||||
/* #define MAX_DATA_SIZE 1024 */ /* defined in Lossless_UDP.h */
|
||||
#define MAX_QUEUE_NUM 16
|
||||
|
||||
/* maximum number of data packets in the buffer */
|
||||
#define BUFFER_PACKET_NUM (16-1)
|
||||
|
||||
/* Lossless UDP connection timeout.
|
||||
timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */
|
||||
/* timeout per connection is randomly set between CONNEXION_TIMEOUT and 2*CONNEXION_TIMEOUT */
|
||||
#define CONNEXION_TIMEOUT 5
|
||||
|
||||
/* initial amount of sync/hanshake packets to send per second. */
|
||||
#define SYNC_RATE 2
|
||||
#define SYNC_RATE 2
|
||||
|
||||
/* initial send rate of data. */
|
||||
#define DATA_SYNC_RATE 30
|
||||
#define DATA_SYNC_RATE 30
|
||||
|
||||
typedef struct {
|
||||
uint8_t data[MAX_DATA_SIZE];
|
||||
uint8_t data[MAX_DATA_SIZE];
|
||||
uint16_t size;
|
||||
} Data;
|
||||
|
||||
typedef struct {
|
||||
IP_Port ip_port;
|
||||
uint8_t status; /* 0 if connection is dead, 1 if attempting handshake,
|
||||
2 if handshake is done (we start sending SYNC packets)
|
||||
3 if we are sending SYNC packets and can send data
|
||||
4 if the connection has timed out. */
|
||||
|
||||
uint8_t inbound; /* 1 or 2 if connection was initiated by someone else, 0 if not.
|
||||
2 if incoming_connection() has not returned it yet, 1 if it has. */
|
||||
/*
|
||||
* 0 if connection is dead, 1 if attempting handshake,
|
||||
* 2 if handshake is done (we start sending SYNC packets)
|
||||
* 3 if we are sending SYNC packets and can send data
|
||||
* 4 if the connection has timed out.
|
||||
*/
|
||||
uint8_t status;
|
||||
|
||||
uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */
|
||||
uint16_t data_rate; /* current data packet send rate packets per second. */
|
||||
uint64_t last_SYNC; /* time at which our last SYNC packet was sent. */
|
||||
uint64_t last_sent; /* time at which our last data or handshake packet was sent. */
|
||||
uint64_t last_recvSYNC; /* time at which we last received a SYNC packet from the other */
|
||||
uint64_t last_recvdata; /* time at which we last received a DATA packet from the other */
|
||||
uint64_t killat; /* time at which to kill the connection */
|
||||
Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */
|
||||
Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */
|
||||
uint32_t handshake_id1;
|
||||
uint32_t handshake_id2;
|
||||
uint32_t recv_packetnum; /* number of data packets received (also used as handshake_id1) */
|
||||
uint32_t orecv_packetnum; /* number of packets received by the other peer */
|
||||
uint32_t sent_packetnum; /* number of data packets sent */
|
||||
uint32_t osent_packetnum; /* number of packets sent by the other peer. */
|
||||
uint32_t sendbuff_packetnum; /* number of latest packet written onto the sendbuffer */
|
||||
uint32_t successful_sent; /* we know all packets before that number were successfully sent */
|
||||
uint32_t successful_read; /* packet number of last packet read with the read_packet function */
|
||||
uint32_t req_packets[BUFFER_PACKET_NUM]; /* list of currently requested packet numbers(by the other person) */
|
||||
uint16_t num_req_paquets; /* total number of currently requested packets(by the other person) */
|
||||
uint8_t recv_counter;
|
||||
uint8_t send_counter;
|
||||
uint8_t timeout; /* connection timeout in seconds. */
|
||||
/*
|
||||
* 1 or 2 if connection was initiated by someone else, 0 if not.
|
||||
* 2 if incoming_connection() has not returned it yet, 1 if it has.
|
||||
*/
|
||||
uint8_t inbound;
|
||||
|
||||
uint16_t SYNC_rate; /* current SYNC packet send rate packets per second. */
|
||||
uint16_t data_rate; /* current data packet send rate packets per second. */
|
||||
|
||||
uint64_t last_SYNC; /* time our last SYNC packet was sent. */
|
||||
uint64_t last_sent; /* time our last data or handshake packet was sent. */
|
||||
uint64_t last_recvSYNC; /* time we last received a SYNC packet from the other */
|
||||
uint64_t last_recvdata; /* time we last received a DATA packet from the other */
|
||||
uint64_t killat; /* time to kill the connection */
|
||||
|
||||
Data sendbuffer[MAX_QUEUE_NUM]; /* packet send buffer. */
|
||||
Data recvbuffer[MAX_QUEUE_NUM]; /* packet receive buffer. */
|
||||
|
||||
uint32_t handshake_id1;
|
||||
uint32_t handshake_id2;
|
||||
|
||||
/* number of data packets received (also used as handshake_id1) */
|
||||
uint32_t recv_packetnum;
|
||||
|
||||
/* number of packets received by the other peer */
|
||||
uint32_t orecv_packetnum;
|
||||
|
||||
/* number of data packets sent */
|
||||
uint32_t sent_packetnum;
|
||||
|
||||
/* number of packets sent by the other peer. */
|
||||
uint32_t osent_packetnum;
|
||||
|
||||
/* number of latest packet written onto the sendbuffer */
|
||||
uint32_t sendbuff_packetnum;
|
||||
|
||||
/* we know all packets before that number were successfully sent */
|
||||
uint32_t successful_sent;
|
||||
|
||||
/* packet number of last packet read with the read_packet function */
|
||||
uint32_t successful_read;
|
||||
|
||||
/* list of currently requested packet numbers(by the other person) */
|
||||
uint32_t req_packets[BUFFER_PACKET_NUM];
|
||||
|
||||
/* total number of currently requested packets(by the other person) */
|
||||
uint16_t num_req_paquets;
|
||||
|
||||
uint8_t recv_counter;
|
||||
uint8_t send_counter;
|
||||
uint8_t timeout; /* connection timeout in seconds. */
|
||||
} Connection;
|
||||
|
||||
|
||||
@ -94,26 +122,33 @@ static uint32_t connections_number; /* Number of connections in connections arra
|
||||
|
||||
/* Functions */
|
||||
|
||||
/* get connection id from IP_Port
|
||||
return -1 if there are no connections like we are looking for
|
||||
return id if it found it */
|
||||
/*
|
||||
* Get connection id from IP_Port
|
||||
* Return -1 if there are no connections like we are looking for
|
||||
* Return id if it found it
|
||||
*/
|
||||
int getconnection_id(IP_Port ip_port)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < MAX_CONNECTIONS; ++i) {
|
||||
if (connections[i].ip_port.ip.i == ip_port.ip.i &&
|
||||
connections[i].ip_port.port == ip_port.port && connections[i].status > 0)
|
||||
connections[i].ip_port.port == ip_port.port &&
|
||||
connections[i].status > 0)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* table of random numbers used below. */
|
||||
static uint32_t randtable[6][256];
|
||||
|
||||
/* generate a handshake_id which depends on the ip_port.
|
||||
this function will always give one unique handshake_id per ip_port.
|
||||
TODO: make this better */
|
||||
/*
|
||||
* Generate a handshake_id which depends on the ip_port.
|
||||
* This function will always give one unique handshake_id per ip_port.
|
||||
*
|
||||
* TODO: make this better
|
||||
*/
|
||||
uint32_t handshake_id(IP_Port source)
|
||||
{
|
||||
uint32_t id = 0, i;
|
||||
@ -124,21 +159,27 @@ uint32_t handshake_id(IP_Port source)
|
||||
}
|
||||
if (id == 0) /* id can't be zero */
|
||||
id = 1;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
/* change the hnshake id associated with that ip_port
|
||||
TODO: make this better */
|
||||
/*
|
||||
* Change the hanshake id associated with that ip_port
|
||||
*
|
||||
* TODO: make this better
|
||||
*/
|
||||
void change_handshake(IP_Port source)
|
||||
{
|
||||
uint8_t rand = random_int() % 4;
|
||||
randtable[rand][((uint8_t *)&source)[rand]] = random_int();
|
||||
}
|
||||
|
||||
/* initialize a new connection to ip_port
|
||||
returns an integer corresponding to the connection id.
|
||||
return -1 if it could not initialize the connection.
|
||||
if there already was an existing connection to that ip_port return its number. */
|
||||
/*
|
||||
* Initialize a new connection to ip_port
|
||||
* Returns an integer corresponding to the connection idt
|
||||
* Return -1 if it could not initialize the connectiont
|
||||
* If there already was an existing connection to that ip_port return its number.
|
||||
*/
|
||||
int new_connection(IP_Port ip_port)
|
||||
{
|
||||
int connect = getconnection_id(ip_port);
|
||||
@ -148,8 +189,10 @@ int new_connection(IP_Port ip_port)
|
||||
if(connections_number == connections_length) {
|
||||
Connection * temp;
|
||||
temp = realloc(connections, sizeof(Connection) * (connections_length + 1));
|
||||
|
||||
if(temp == NULL)
|
||||
return -1;
|
||||
|
||||
memset(&temp[connections_length], 0, sizeof(Connection));
|
||||
++connections_length;
|
||||
connections = temp;
|
||||
@ -159,31 +202,37 @@ int new_connection(IP_Port ip_port)
|
||||
for (i = 0; i < MAX_CONNECTIONS; ++i) {
|
||||
if(connections[i].status == 0) {
|
||||
memset(&connections[i], 0, sizeof(Connection));
|
||||
connections[i].ip_port = ip_port;
|
||||
connections[i].status = 1;
|
||||
connections[i].inbound = 0;
|
||||
connections[i].handshake_id1 = handshake_id(ip_port);
|
||||
connections[i].sent_packetnum = connections[i].handshake_id1;
|
||||
connections[i].sendbuff_packetnum = connections[i].handshake_id1;
|
||||
connections[i].successful_sent = connections[i].handshake_id1;
|
||||
connections[i].SYNC_rate = SYNC_RATE;
|
||||
connections[i].data_rate = DATA_SYNC_RATE;
|
||||
connections[i].last_recvSYNC = current_time();
|
||||
connections[i].last_sent = current_time();
|
||||
connections[i].killat = ~0;
|
||||
connections[i].send_counter = 0;
|
||||
/* add randomness to timeout to prevent connections getting stuck in a loop. */
|
||||
connections[i].timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT;
|
||||
|
||||
connections[i] = (Connection) {
|
||||
.ip_port = ip_port,
|
||||
.status = 1,
|
||||
.inbound = 0,
|
||||
.handshake_id1 = handshake_id(ip_port),
|
||||
.sent_packetnum = connections[i].handshake_id1,
|
||||
.sendbuff_packetnum = connections[i].handshake_id1,
|
||||
.successful_sent = connections[i].handshake_id1,
|
||||
.SYNC_rate = SYNC_RATE,
|
||||
.data_rate = DATA_SYNC_RATE,
|
||||
.last_recvSYNC = current_time(),
|
||||
.last_sent = current_time(),
|
||||
.killat = ~0,
|
||||
.send_counter = 0,
|
||||
/* add randomness to timeout to prevent connections getting stuck in a loop. */
|
||||
.timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT
|
||||
};
|
||||
++connections_number;
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* initialize a new inbound connection from ip_port
|
||||
returns an integer corresponding to the connection id.
|
||||
return -1 if it could not initialize the connection. */
|
||||
/*
|
||||
* Initialize a new inbound connection from ip_port
|
||||
* Returns an integer corresponding to the connection id.
|
||||
* Return -1 if it could not initialize the connection.
|
||||
*/
|
||||
int new_inconnection(IP_Port ip_port)
|
||||
{
|
||||
if (getconnection_id(ip_port) != -1)
|
||||
@ -192,8 +241,10 @@ int new_inconnection(IP_Port ip_port)
|
||||
if(connections_number == connections_length) {
|
||||
Connection * temp;
|
||||
temp = realloc(connections, sizeof(Connection) * (connections_length + 1));
|
||||
|
||||
if(temp == NULL)
|
||||
return -1;
|
||||
|
||||
memset(&temp[connections_length], 0, sizeof(Connection));
|
||||
++connections_length;
|
||||
connections = temp;
|
||||
@ -203,18 +254,23 @@ int new_inconnection(IP_Port ip_port)
|
||||
for (i = 0; i < MAX_CONNECTIONS; ++i) {
|
||||
if (connections[i].status == 0) {
|
||||
memset(&connections[i], 0, sizeof(Connection));
|
||||
connections[i].ip_port = ip_port;
|
||||
connections[i].status = 2;
|
||||
connections[i].inbound = 2;
|
||||
connections[i].SYNC_rate = SYNC_RATE;
|
||||
connections[i].data_rate = DATA_SYNC_RATE;
|
||||
connections[i].last_recvSYNC = current_time();
|
||||
connections[i].last_sent = current_time();
|
||||
/* add randomness to timeout to prevent connections getting stuck in a loop. */
|
||||
connections[i].timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT;
|
||||
/* if this connection isn't handled within the timeout kill it. */
|
||||
connections[i].killat = current_time() + 1000000UL*connections[i].timeout;
|
||||
connections[i].send_counter = 127;
|
||||
|
||||
connections[i] = (Connection){
|
||||
.ip_port = ip_port,
|
||||
.status = 2,
|
||||
.inbound = 2,
|
||||
.SYNC_rate = SYNC_RATE,
|
||||
.data_rate = DATA_SYNC_RATE,
|
||||
.last_recvSYNC = current_time(),
|
||||
.last_sent = current_time(),
|
||||
.send_counter = 127,
|
||||
|
||||
/* add randomness to timeout to prevent connections getting stuck in a loop. */
|
||||
.timeout = CONNEXION_TIMEOUT + rand() % CONNEXION_TIMEOUT,
|
||||
|
||||
/* if this connection isn't handled within the timeout kill it. */
|
||||
.killat = current_time() + 1000000UL*connections[i].timeout
|
||||
};
|
||||
++connections_number;
|
||||
return i;
|
||||
}
|
||||
@ -222,8 +278,10 @@ int new_inconnection(IP_Port ip_port)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* returns an integer corresponding to the next connection in our incoming connection list
|
||||
return -1 if there are no new incoming connections in the list. */
|
||||
/*
|
||||
* Returns an integer corresponding to the next connection in our incoming connection list.
|
||||
* Return -1 if there are no new incoming connections in the list.
|
||||
*/
|
||||
int incoming_connection()
|
||||
{
|
||||
uint32_t i;
|
||||
@ -233,9 +291,11 @@ int incoming_connection()
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
/*Try to free some memory from the connections array.*/
|
||||
|
||||
/* Try to free some memory from the connections array. */
|
||||
static void free_connections()
|
||||
{
|
||||
uint32_t i;
|
||||
@ -245,16 +305,20 @@ static void free_connections()
|
||||
|
||||
if(connections_length == i)
|
||||
return;
|
||||
|
||||
Connection * temp;
|
||||
temp = realloc(connections, sizeof(Connection) * i);
|
||||
if(temp == NULL && i != 0)
|
||||
return;
|
||||
|
||||
connections = temp;
|
||||
connections_length = i;
|
||||
}
|
||||
|
||||
/* return -1 if it could not kill the connection.
|
||||
return 0 if killed successfully */
|
||||
/*
|
||||
* Return -1 if it could not kill the connection.
|
||||
* Return 0 if killed successfully
|
||||
*/
|
||||
int kill_connection(int connection_id)
|
||||
{
|
||||
if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) {
|
||||
@ -269,9 +333,11 @@ int kill_connection(int connection_id)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* kill connection in seconds seconds.
|
||||
return -1 if it can not kill the connection.
|
||||
return 0 if it will kill it */
|
||||
/*
|
||||
* Kill connection in seconds.
|
||||
* Return -1 if it can not kill the connection.
|
||||
* Return 0 if it will kill it.
|
||||
*/
|
||||
int kill_connection_in(int connection_id, uint32_t seconds)
|
||||
{
|
||||
if (connection_id >= 0 && connection_id < MAX_CONNECTIONS) {
|
||||
@ -283,12 +349,14 @@ int kill_connection_in(int connection_id, uint32_t seconds)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* check if connection is connected
|
||||
return 0 no.
|
||||
return 1 if attempting handshake
|
||||
return 2 if handshake is done
|
||||
return 3 if fully connected
|
||||
return 4 if timed out and waiting to be killed */
|
||||
/*
|
||||
* Check if connection is connected:
|
||||
* Return 0 no.
|
||||
* Return 1 if attempting handshake.
|
||||
* Return 2 if handshake is done.
|
||||
* Return 3 if fully connected.
|
||||
* Return 4 if timed out and waiting to be killed.
|
||||
*/
|
||||
int is_connected(int connection_id)
|
||||
{
|
||||
if (connection_id >= 0 && connection_id < MAX_CONNECTIONS)
|
||||
@ -327,8 +395,10 @@ char id_packet(int connection_id)
|
||||
{
|
||||
if (connection_id < 0 || connection_id >= MAX_CONNECTIONS)
|
||||
return -1;
|
||||
|
||||
if (recvqueue(connection_id) != 0 && connections[connection_id].status != 0)
|
||||
return connections[connection_id].recvbuffer[connections[connection_id].successful_read % MAX_QUEUE_NUM].data[0];
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -338,7 +408,7 @@ int read_packet(int connection_id, uint8_t * data)
|
||||
{
|
||||
if (recvqueue(connection_id) != 0) {
|
||||
uint16_t index = connections[connection_id].successful_read % MAX_QUEUE_NUM;
|
||||
uint16_t size = connections[connection_id].recvbuffer[index].size;
|
||||
uint16_t size = connections[connection_id].recvbuffer[index].size;
|
||||
memcpy(data, connections[connection_id].recvbuffer[index].data, size);
|
||||
++connections[connection_id].successful_read;
|
||||
connections[connection_id].recvbuffer[index].size = 0;
|
||||
@ -347,14 +417,15 @@ int read_packet(int connection_id, uint8_t * data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return 0 if data could not be put in packet queue
|
||||
return 1 if data was put into the queue */
|
||||
/*
|
||||
* Return 0 if data could not be put in packet queue
|
||||
* Return 1 if data was put into the queue
|
||||
*/
|
||||
int write_packet(int connection_id, uint8_t * data, uint32_t length)
|
||||
{
|
||||
if (length > MAX_DATA_SIZE)
|
||||
return 0;
|
||||
if (length == 0)
|
||||
if (length > MAX_DATA_SIZE || length == 0)
|
||||
return 0;
|
||||
|
||||
if (sendqueue(connection_id) < BUFFER_PACKET_NUM) {
|
||||
uint32_t index = connections[connection_id].sendbuff_packetnum % MAX_QUEUE_NUM;
|
||||
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)
|
||||
connections[connection_id].sendbuff_packetnum++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -371,8 +443,11 @@ uint32_t missing_packets(int connection_id, uint32_t * requested)
|
||||
uint32_t number = 0;
|
||||
uint32_t i;
|
||||
uint32_t temp;
|
||||
if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1)) /* don't request packets if the buffer is full. */
|
||||
|
||||
/* don't request packets if the buffer is full. */
|
||||
if (recvqueue(connection_id) >= (BUFFER_PACKET_NUM - 1))
|
||||
return 0;
|
||||
|
||||
for (i = connections[connection_id].recv_packetnum; i != connections[connection_id].osent_packetnum; i++) {
|
||||
if(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size == 0) {
|
||||
temp = htonl(i);
|
||||
@ -380,14 +455,19 @@ uint32_t missing_packets(int connection_id, uint32_t * requested)
|
||||
++number;
|
||||
}
|
||||
}
|
||||
|
||||
if(number == 0)
|
||||
connections[connection_id].recv_packetnum = connections[connection_id].osent_packetnum;
|
||||
|
||||
return number;
|
||||
}
|
||||
|
||||
/* Packet sending functions
|
||||
One per packet type.
|
||||
see docs/Lossless_UDP.txt for more information. */
|
||||
/*
|
||||
* BEGIN Packet sending functions
|
||||
* One per packet type.
|
||||
* see docs/Lossless_UDP.txt for more information.
|
||||
*/
|
||||
|
||||
int send_handshake(IP_Port ip_port, uint32_t handshake_id1, uint32_t handshake_id2)
|
||||
{
|
||||
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
|
||||
memcpy(packet + 1, &temp, 4);
|
||||
temp = htonl(handshake_id2);
|
||||
memcpy(packet + 5, &temp, 4);
|
||||
|
||||
return sendpacket(ip_port, packet, sizeof(packet));
|
||||
}
|
||||
|
||||
int send_SYNC(uint32_t connection_id)
|
||||
{
|
||||
|
||||
uint8_t packet[(BUFFER_PACKET_NUM*4 + 4 + 4 + 2)];
|
||||
uint16_t index = 0;
|
||||
|
||||
IP_Port ip_port = connections[connection_id].ip_port;
|
||||
uint8_t counter = connections[connection_id].send_counter;
|
||||
IP_Port ip_port = connections[connection_id].ip_port;
|
||||
uint8_t counter = connections[connection_id].send_counter;
|
||||
uint32_t recv_packetnum = htonl(connections[connection_id].recv_packetnum);
|
||||
uint32_t sent_packetnum = htonl(connections[connection_id].sent_packetnum);
|
||||
|
||||
uint32_t requested[BUFFER_PACKET_NUM];
|
||||
uint32_t number = missing_packets(connection_id, requested);
|
||||
uint32_t number = missing_packets(connection_id, requested);
|
||||
|
||||
packet[0] = 17;
|
||||
index += 1;
|
||||
@ -462,17 +543,24 @@ int send_DATA(uint32_t connection_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* END of packet sending functions */
|
||||
/*
|
||||
* END of packet sending functions
|
||||
*
|
||||
*
|
||||
* BEGIN Packet handling functions
|
||||
* One to handle each type of packets we receive
|
||||
*/
|
||||
|
||||
/* Packet handling functions
|
||||
One to handle each type of packets we receive
|
||||
return 0 if handled correctly, 1 if packet is bad. */
|
||||
|
||||
/* Return 0 if handled correctly, 1 if packet is bad. */
|
||||
int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
|
||||
{
|
||||
if (length != (1 + 4 + 4))
|
||||
return 1;
|
||||
|
||||
uint32_t temp;
|
||||
uint32_t handshake_id1, handshake_id2;
|
||||
|
||||
int connection = getconnection_id(source);
|
||||
memcpy(&temp, packet + 1, 4);
|
||||
handshake_id1 = ntohl(temp);
|
||||
@ -485,21 +573,22 @@ int handle_handshake(uint8_t * packet, uint32_t length, IP_Port source)
|
||||
}
|
||||
if (is_connected(connection) != 1)
|
||||
return 1;
|
||||
if (handshake_id2 == connections[connection].handshake_id1) { /* if handshake_id2 is what we sent previously as handshake_id1 */
|
||||
|
||||
/* if handshake_id2 is what we sent previously as handshake_id1 */
|
||||
if (handshake_id2 == connections[connection].handshake_id1) {
|
||||
connections[connection].status = 2;
|
||||
/* NOTE: is this necessary?
|
||||
connections[connection].handshake_id2 = handshake_id1; */
|
||||
connections[connection].orecv_packetnum = handshake_id2;
|
||||
connections[connection].osent_packetnum = handshake_id1;
|
||||
connections[connection].recv_packetnum = handshake_id1;
|
||||
connections[connection].recv_packetnum = handshake_id1;
|
||||
connections[connection].successful_read = handshake_id1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns 1 if sync packet is valid
|
||||
0 if not. */
|
||||
/* returns 1 if sync packet is valid 0 if not. */
|
||||
int SYNC_valid(uint32_t length)
|
||||
{
|
||||
if (length < 4 + 4 + 2)
|
||||
@ -510,19 +599,19 @@ int SYNC_valid(uint32_t length)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* case 1: */
|
||||
/* case 1 in handle_SYNC: */
|
||||
int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnum)
|
||||
{
|
||||
if (handshake_id(source) == recv_packetnum) {
|
||||
int x = new_inconnection(source);
|
||||
if (x != -1) {
|
||||
connections[x].orecv_packetnum = recv_packetnum;
|
||||
connections[x].sent_packetnum = recv_packetnum;
|
||||
connections[x].orecv_packetnum = recv_packetnum;
|
||||
connections[x].sent_packetnum = recv_packetnum;
|
||||
connections[x].sendbuff_packetnum = recv_packetnum;
|
||||
connections[x].successful_sent = recv_packetnum;
|
||||
connections[x].osent_packetnum = sent_packetnum;
|
||||
connections[x].recv_packetnum = sent_packetnum;
|
||||
connections[x].successful_read = sent_packetnum;
|
||||
connections[x].successful_sent = recv_packetnum;
|
||||
connections[x].osent_packetnum = sent_packetnum;
|
||||
connections[x].recv_packetnum = sent_packetnum;
|
||||
connections[x].successful_read = sent_packetnum;
|
||||
|
||||
return x;
|
||||
}
|
||||
@ -530,7 +619,7 @@ int handle_SYNC1(IP_Port source, uint32_t recv_packetnum, uint32_t sent_packetnu
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* case 2: */
|
||||
/* case 2 in handle_SYNC: */
|
||||
int handle_SYNC2(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum)
|
||||
{
|
||||
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
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* case 3: */
|
||||
/* case 3 in handle_SYNC: */
|
||||
int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, uint32_t sent_packetnum, uint32_t * req_packets,
|
||||
uint16_t number)
|
||||
{
|
||||
@ -553,17 +642,25 @@ int handle_SYNC3(int connection_id, uint8_t counter, uint32_t recv_packetnum, ui
|
||||
uint32_t comp_2 = (sent_packetnum - connections[connection_id].successful_read); */
|
||||
uint32_t comp_1 = (recv_packetnum - connections[connection_id].orecv_packetnum);
|
||||
uint32_t comp_2 = (sent_packetnum - connections[connection_id].osent_packetnum);
|
||||
if (comp_1 <= BUFFER_PACKET_NUM && comp_2 <= BUFFER_PACKET_NUM && comp_counter < 10 && comp_counter != 0) { /* packet valid */
|
||||
|
||||
/* packet valid */
|
||||
if (comp_1 <= BUFFER_PACKET_NUM &&
|
||||
comp_2 <= BUFFER_PACKET_NUM &&
|
||||
comp_counter < 10 && comp_counter != 0) {
|
||||
|
||||
connections[connection_id].orecv_packetnum = recv_packetnum;
|
||||
connections[connection_id].osent_packetnum = sent_packetnum;
|
||||
connections[connection_id].successful_sent = recv_packetnum;
|
||||
connections[connection_id].last_recvSYNC = current_time();
|
||||
connections[connection_id].recv_counter = counter;
|
||||
connections[connection_id].last_recvSYNC = current_time();
|
||||
connections[connection_id].recv_counter = counter;
|
||||
|
||||
++connections[connection_id].send_counter;
|
||||
|
||||
for (i = 0; i < number; ++i) {
|
||||
temp = ntohl(req_packets[i]);
|
||||
memcpy(connections[connection_id].req_packets + i, &temp, 4 * number);
|
||||
}
|
||||
|
||||
connections[connection_id].num_req_paquets = number;
|
||||
return 0;
|
||||
}
|
||||
@ -575,6 +672,7 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source)
|
||||
|
||||
if (!SYNC_valid(length))
|
||||
return 1;
|
||||
|
||||
int connection = getconnection_id(source);
|
||||
uint8_t counter;
|
||||
uint32_t temp;
|
||||
@ -587,19 +685,27 @@ int handle_SYNC(uint8_t *packet, uint32_t length, IP_Port source)
|
||||
recv_packetnum = ntohl(temp);
|
||||
memcpy(&temp,packet + 6, 4);
|
||||
sent_packetnum = ntohl(temp);
|
||||
|
||||
if (number != 0)
|
||||
memcpy(req_packets, packet + 10, 4 * number);
|
||||
|
||||
if (connection == -1)
|
||||
return handle_SYNC1(source, recv_packetnum, sent_packetnum);
|
||||
|
||||
if (connections[connection].status == 2)
|
||||
return handle_SYNC2(connection, counter, recv_packetnum, sent_packetnum);
|
||||
return handle_SYNC2(connection, counter,
|
||||
recv_packetnum, sent_packetnum);
|
||||
|
||||
if (connections[connection].status == 3)
|
||||
return handle_SYNC3(connection, counter, recv_packetnum, sent_packetnum, req_packets, number);
|
||||
return handle_SYNC3(connection, counter, recv_packetnum,
|
||||
sent_packetnum, req_packets, number);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* add a packet to the received buffer and set the recv_packetnum of the connection to its proper value.
|
||||
return 1 if data was too big, 0 if not. */
|
||||
/*
|
||||
* Add a packet to the received buffer and set the recv_packetnum of the
|
||||
* connection to its proper value. Return 1 if data was too big, 0 if not.
|
||||
*/
|
||||
int add_recv(int connection_id, uint32_t data_num, uint8_t *data, uint16_t size)
|
||||
{
|
||||
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)
|
||||
uint32_t i;
|
||||
uint32_t maxnum = connections[connection_id].successful_read + BUFFER_PACKET_NUM;
|
||||
uint32_t sent_packet = data_num - connections[connection_id].osent_packetnum;
|
||||
|
||||
for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
|
||||
if (i == data_num) {
|
||||
memcpy(connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].data, data, size);
|
||||
|
||||
connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size = size;
|
||||
connections[connection_id].last_recvdata = current_time();
|
||||
if (sent_packet < BUFFER_PACKET_NUM)
|
||||
|
||||
if (sent_packet < BUFFER_PACKET_NUM) {
|
||||
connections[connection_id].osent_packetnum = data_num;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = connections[connection_id].recv_packetnum; i != maxnum; ++i) {
|
||||
if (connections[connection_id].recvbuffer[i % MAX_QUEUE_NUM].size != 0)
|
||||
connections[connection_id].recv_packetnum = i;
|
||||
@ -635,25 +747,30 @@ int handle_data(uint8_t *packet, uint32_t length, IP_Port source)
|
||||
if (connection == -1)
|
||||
return 1;
|
||||
|
||||
if (connections[connection].status != 3) /* Drop the data packet if connection is not connected. */
|
||||
/* Drop the data packet if connection is not connected. */
|
||||
if (connections[connection].status != 3)
|
||||
return 1;
|
||||
|
||||
if (length > 1 + 4 + MAX_DATA_SIZE || length < 1 + 4 + 1)
|
||||
return 1;
|
||||
|
||||
uint32_t temp;
|
||||
uint32_t number;
|
||||
uint16_t size = length - 1 - 4;
|
||||
|
||||
memcpy(&temp, packet + 1, 4);
|
||||
number = ntohl(temp);
|
||||
|
||||
return add_recv(connection, number, packet + 5, size);
|
||||
}
|
||||
|
||||
/* END of packet handling functions */
|
||||
/*
|
||||
* END of packet handling functions
|
||||
*/
|
||||
|
||||
int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source)
|
||||
{
|
||||
switch (packet[0]) { //TODO: check if no break statement is correct???
|
||||
switch (packet[0]) {
|
||||
case 16:
|
||||
return handle_handshake(packet, length, source);
|
||||
|
||||
@ -670,8 +787,10 @@ int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Send handshake requests
|
||||
handshake packets are sent at the same rate as SYNC packets */
|
||||
/*
|
||||
* Send handshake requests
|
||||
* handshake packets are sent at the same rate as SYNC packets
|
||||
*/
|
||||
void doNew()
|
||||
{
|
||||
uint32_t i;
|
||||
@ -684,10 +803,13 @@ void doNew()
|
||||
}
|
||||
|
||||
/* kill all timed out connections */
|
||||
if ( connections[i].status > 0 && (connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
|
||||
connections[i].status != 4)
|
||||
/* kill_connection(i); */
|
||||
if (connections[i].status > 0 &&
|
||||
(connections[i].last_recvSYNC + connections[i].timeout * 1000000UL) < temp_time &&
|
||||
connections[i].status != 4) {
|
||||
connections[i].status = 4;
|
||||
/* kill_connection(i); */
|
||||
}
|
||||
|
||||
if (connections[i].status > 0 && connections[i].killat < temp_time)
|
||||
kill_connection(i);
|
||||
}
|
||||
@ -720,11 +842,13 @@ void doData()
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: flow control.
|
||||
automatically adjusts send rates of packets for optimal transmission. */
|
||||
|
||||
#define MAX_SYNC_RATE 10
|
||||
|
||||
/*
|
||||
* Automatically adjusts send rates of packets for optimal transmission.
|
||||
*
|
||||
* TODO: flow control.
|
||||
*/
|
||||
void adjustRates()
|
||||
{
|
||||
uint32_t i;
|
||||
@ -744,8 +868,7 @@ void adjustRates()
|
||||
}
|
||||
}
|
||||
|
||||
/* Call this function a couple times per second
|
||||
It's the main loop. */
|
||||
/* Call this function a couple times per second It's the main loop. */
|
||||
void doLossless_UDP()
|
||||
{
|
||||
doNew();
|
||||
|
@ -33,70 +33,90 @@ extern "C" {
|
||||
/* maximum length of the data in the data packets */
|
||||
#define MAX_DATA_SIZE 1024
|
||||
|
||||
/* Functions */
|
||||
|
||||
/* initialize a new connection to ip_port
|
||||
returns an integer corresponding to the connection id.
|
||||
return -1 if it could not initialize the connection.
|
||||
if there already was an existing connection to that ip_port return its number. */
|
||||
/*
|
||||
* Initialize a new connection to ip_port
|
||||
* Returns an integer corresponding to the connection id.
|
||||
* Return -1 if it could not initialize the connection.
|
||||
* Return number if there already was an existing connection to that ip_port.
|
||||
*/
|
||||
int new_connection(IP_Port ip_port);
|
||||
|
||||
/* get connection id from IP_Port
|
||||
return -1 if there are no connections like we are looking for
|
||||
return id if it found it */
|
||||
/*
|
||||
* Get connection id from IP_Port.
|
||||
* Return -1 if there are no connections like we are looking for.
|
||||
* Return id if it found it .
|
||||
*/
|
||||
int getconnection_id(IP_Port ip_port);
|
||||
|
||||
/* returns an integer corresponding to the next connection in our imcoming connection list
|
||||
return -1 if there are no new incoming connections in the list. */
|
||||
/*
|
||||
* Returns an int corresponding to the next connection in our imcoming connection list
|
||||
* Return -1 if there are no new incoming connections in the list.
|
||||
*/
|
||||
int incoming_connection();
|
||||
|
||||
/* return -1 if it could not kill the connection.
|
||||
return 0 if killed successfully */
|
||||
/*
|
||||
* Return -1 if it could not kill the connection.
|
||||
* Return 0 if killed successfully
|
||||
*/
|
||||
int kill_connection(int connection_id);
|
||||
|
||||
/* kill connection in seconds seconds.
|
||||
return -1 if it can not kill the connection.
|
||||
return 0 if it will kill it */
|
||||
/*
|
||||
* Kill connection in seconds seconds.
|
||||
* Return -1 if it can not kill the connection.
|
||||
* Return 0 if it will kill it
|
||||
*/
|
||||
int kill_connection_in(int connection_id, uint32_t seconds);
|
||||
|
||||
/* returns the ip_port of the corresponding connection.
|
||||
return 0 if there is no such connection. */
|
||||
/*
|
||||
* Returns the ip_port of the corresponding connection.
|
||||
* Return 0 if there is no such connection.
|
||||
*/
|
||||
IP_Port connection_ip(int connection_id);
|
||||
|
||||
/* returns the id of the next packet in the queue
|
||||
return -1 if no packet in queue */
|
||||
/*
|
||||
* Returns the id of the next packet in the queue
|
||||
* Return -1 if no packet in queue
|
||||
*/
|
||||
char id_packet(int connection_id);
|
||||
|
||||
/* return 0 if there is no received data in the buffer.
|
||||
return length of received packet if successful */
|
||||
/*
|
||||
* Return 0 if there is no received data in the buffer.
|
||||
* Return length of received packet if successful
|
||||
*/
|
||||
int read_packet(int connection_id, uint8_t *data);
|
||||
|
||||
/* return 0 if data could not be put in packet queue
|
||||
return 1 if data was put into the queue */
|
||||
/*
|
||||
* Return 0 if data could not be put in packet queue
|
||||
* Return 1 if data was put into the queue
|
||||
*/
|
||||
int write_packet(int connection_id, uint8_t *data, uint32_t length);
|
||||
|
||||
/* returns the number of packets in the queue waiting to be successfully sent. */
|
||||
/* Returns the number of packets in the queue waiting to be successfully sent. */
|
||||
uint32_t sendqueue(int connection_id);
|
||||
|
||||
/* returns the number of packets in the queue waiting to be successfully read with read_packet(...) */
|
||||
/*
|
||||
* returns the number of packets in the queue waiting to be successfully
|
||||
* read with read_packet(...)
|
||||
*/
|
||||
uint32_t recvqueue(int connection_id);
|
||||
|
||||
/* check if connection is connected
|
||||
return 0 no.
|
||||
return 1 if attempting handshake
|
||||
return 2 if handshake is done
|
||||
return 3 if fully connected
|
||||
return 4 if timed out and wating to be killed */
|
||||
/* Check if connection is connected:
|
||||
* Return 0 no.
|
||||
* Return 1 if attempting handshake.
|
||||
* Return 2 if handshake is done.
|
||||
* Return 3 if fully connected.
|
||||
* Return 4 if timed out and wating to be killed.
|
||||
*/
|
||||
int is_connected(int connection_id);
|
||||
|
||||
/* Call this function a couple times per second
|
||||
It's the main loop. */
|
||||
/* Call this function a couple times per second It's the main loop. */
|
||||
void doLossless_UDP();
|
||||
|
||||
|
||||
/* if we receive a Lossless_UDP packet we call this function so it can be handled.
|
||||
return 0 if packet is handled correctly.
|
||||
return 1 if it didn't handle the packet or if the packet was shit. */
|
||||
/*
|
||||
* If we receive a Lossless_UDP packet, call this function so it can be handled.
|
||||
* Return 0 if packet is handled correctly.
|
||||
* Return 1 if it didn't handle the packet or if the packet was shit.
|
||||
*/
|
||||
int LosslessUDP_handlepacket(uint8_t *packet, uint32_t length, IP_Port source);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -27,7 +27,7 @@
|
||||
typedef struct {
|
||||
uint8_t client_id[CLIENT_ID_SIZE];
|
||||
int crypt_connection_id;
|
||||
int friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */
|
||||
int64_t friend_request_id; /* id of the friend request corresponding to the current friend request to the current friend. */
|
||||
uint8_t status; /* 0 if no friend, 1 if added, 2 if friend request sent, 3 if confirmed friend, 4 if online. */
|
||||
uint8_t info[MAX_DATA_SIZE]; /* the data that is sent during the friend requests we do */
|
||||
uint8_t name[MAX_NAME_LENGTH];
|
||||
@ -94,24 +94,31 @@ int getclient_id(int friend_id, uint8_t *client_id)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* add a friend
|
||||
set the data that will be sent along with friend request
|
||||
client_id is the client id of the friend
|
||||
data is the data and length is the length
|
||||
returns the friend number if success
|
||||
return -1 if key length is wrong.
|
||||
return -2 if user's own key
|
||||
return -3 if already a friend
|
||||
return -4 for other*/
|
||||
/*
|
||||
* add a friend
|
||||
* set the data that will be sent along with friend request
|
||||
* client_id is the client id of the friend
|
||||
* data is the data and length is the length
|
||||
* returns the friend number if success
|
||||
* return -1 if message length is too long
|
||||
* return -2 if no message (message length must be >= 1 byte)
|
||||
* return -3 if user's own key
|
||||
* return -4 if friend request already sent or already a friend
|
||||
* return -5 for unknown error
|
||||
*/
|
||||
int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
|
||||
{
|
||||
if (length == 0 || length >=
|
||||
(MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES - crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES))
|
||||
if (length >= (MAX_DATA_SIZE - crypto_box_PUBLICKEYBYTES
|
||||
- crypto_box_NONCEBYTES - crypto_box_BOXZEROBYTES
|
||||
+ crypto_box_ZEROBYTES))
|
||||
return -1;
|
||||
if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
||||
if (length < 1)
|
||||
return -2;
|
||||
if (getfriend_id(client_id) != -1)
|
||||
if (memcmp(client_id, self_public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
||||
return -3;
|
||||
if (getfriend_id(client_id) != -1)
|
||||
return -4;
|
||||
|
||||
uint32_t i;
|
||||
for (i = 0; i <= numfriends; ++i) { /*TODO: dynamic memory allocation, this will segfault if there are more than MAX_NUM_FRIENDS*/
|
||||
if(friendlist[i].status == 0) {
|
||||
@ -129,7 +136,7 @@ int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -4;
|
||||
return -5;
|
||||
}
|
||||
|
||||
int m_addfriend_norequest(uint8_t * client_id)
|
||||
@ -484,7 +491,7 @@ static void doInbound()
|
||||
/*Interval in seconds between LAN discovery packet sending*/
|
||||
#define LAN_DISCOVERY_INTERVAL 60
|
||||
|
||||
static uint32_t last_LANdiscovery;
|
||||
static int64_t last_LANdiscovery;
|
||||
|
||||
/*Send a LAN discovery packet every LAN_DISCOVERY_INTERVAL seconds*/
|
||||
static void LANdiscovery()
|
||||
|
@ -45,15 +45,18 @@ extern "C" {
|
||||
/* don't assume MAX_USERSTATUS_LENGTH will stay at 128, it may be increased
|
||||
to an absurdly large number later */
|
||||
|
||||
/* add a friend
|
||||
set the data that will be sent along with friend request
|
||||
client_id is the client id of the friend
|
||||
data is the data and length is the length
|
||||
returns the friend number if success
|
||||
return -1 if key length is wrong.
|
||||
return -2 if user's own key
|
||||
return -3 if already a friend
|
||||
return -4 for other*/
|
||||
/*
|
||||
* add a friend
|
||||
* set the data that will be sent along with friend request
|
||||
* client_id is the client id of the friend
|
||||
* data is the data and length is the length
|
||||
* returns the friend number if success
|
||||
* return -1 if message length is too long
|
||||
* return -2 if no message (message length must be >= 1 byte)
|
||||
* return -3 if user's own key
|
||||
* return -4 if friend request already sent or already a friend
|
||||
* return -5 for unknown error
|
||||
*/
|
||||
int m_addfriend(uint8_t *client_id, uint8_t *data, uint16_t length);
|
||||
|
||||
|
||||
|
@ -48,6 +48,12 @@ typedef struct {
|
||||
|
||||
static Crypto_Connection crypto_connections[MAX_CRYPTO_CONNECTIONS];
|
||||
|
||||
#define CONN_NO_CONNECTION 0
|
||||
#define CONN_HANDSHAKE_SENT 1
|
||||
#define CONN_NOT_CONFIRMED 2
|
||||
#define CONN_ESTABLISHED 3
|
||||
#define CONN_TIMED_OUT 4
|
||||
|
||||
#define MAX_INCOMING 64
|
||||
|
||||
/* keeps track of the connection numbers for friends request so we can check later if they were sent */
|
||||
@ -75,10 +81,9 @@ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
|
||||
uint32_t i;
|
||||
uint32_t check = 0;
|
||||
for(i = 0; i < crypto_box_BOXZEROBYTES; ++i) {
|
||||
if (temp_encrypted[i] != 0)
|
||||
check = 1;
|
||||
check |= temp_encrypted[i] ^ 0;
|
||||
}
|
||||
if(check == 1)
|
||||
if(check != 0)
|
||||
return -1;
|
||||
|
||||
/* unpad the encrypted message */
|
||||
@ -110,10 +115,9 @@ int decrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce,
|
||||
uint32_t i;
|
||||
uint32_t check = 0;
|
||||
for(i = 0; i < crypto_box_ZEROBYTES; ++i) {
|
||||
if (temp_plain[i] != 0)
|
||||
check = 1;
|
||||
check |= temp_plain[i] ^ 0;
|
||||
}
|
||||
if(check == 1)
|
||||
if(check != 0)
|
||||
return -1;
|
||||
|
||||
/* unpad the plain message */
|
||||
@ -149,7 +153,7 @@ int read_cryptpacket(int crypt_connection_id, uint8_t *data)
|
||||
{
|
||||
if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
|
||||
return 0;
|
||||
if (crypto_connections[crypt_connection_id].status != 3)
|
||||
if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
|
||||
return 0;
|
||||
uint8_t temp_data[MAX_DATA_SIZE];
|
||||
int length = read_packet(crypto_connections[crypt_connection_id].number, temp_data);
|
||||
@ -175,7 +179,7 @@ int write_cryptpacket(int crypt_connection_id, uint8_t *data, uint32_t length)
|
||||
return 0;
|
||||
if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE - 1)
|
||||
return 0;
|
||||
if (crypto_connections[crypt_connection_id].status != 3)
|
||||
if (crypto_connections[crypt_connection_id].status != CONN_ESTABLISHED)
|
||||
return 0;
|
||||
uint8_t temp_data[MAX_DATA_SIZE];
|
||||
int len = encrypt_data(crypto_connections[crypt_connection_id].peersessionpublic_key,
|
||||
@ -295,7 +299,7 @@ int getcryptconnection_id(uint8_t *public_key)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
|
||||
if (crypto_connections[i].status > 0)
|
||||
if (crypto_connections[i].status != CONN_NO_CONNECTION)
|
||||
if (memcmp(public_key, crypto_connections[i].public_key, crypto_box_PUBLICKEYBYTES) == 0)
|
||||
return i;
|
||||
}
|
||||
@ -315,12 +319,12 @@ int crypto_connect(uint8_t *public_key, IP_Port ip_port)
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
|
||||
if (crypto_connections[i].status == 0) {
|
||||
if (crypto_connections[i].status == CONN_NO_CONNECTION) {
|
||||
int id = new_connection(ip_port);
|
||||
if (id == -1)
|
||||
return -1;
|
||||
crypto_connections[i].number = id;
|
||||
crypto_connections[i].status = 1;
|
||||
crypto_connections[i].status = CONN_HANDSHAKE_SENT;
|
||||
random_nonce(crypto_connections[i].recv_nonce);
|
||||
memcpy(crypto_connections[i].public_key, public_key, crypto_box_PUBLICKEYBYTES);
|
||||
crypto_box_keypair(crypto_connections[i].sessionpublic_key, crypto_connections[i].sessionsecret_key);
|
||||
@ -374,8 +378,8 @@ int crypto_kill(int crypt_connection_id)
|
||||
{
|
||||
if (crypt_connection_id < 0 || crypt_connection_id >= MAX_CRYPTO_CONNECTIONS)
|
||||
return 1;
|
||||
if (crypto_connections[crypt_connection_id].status != 0) {
|
||||
crypto_connections[crypt_connection_id].status = 0;
|
||||
if (crypto_connections[crypt_connection_id].status != CONN_NO_CONNECTION) {
|
||||
crypto_connections[crypt_connection_id].status = CONN_NO_CONNECTION;
|
||||
kill_connection(crypto_connections[crypt_connection_id].number);
|
||||
memset(&crypto_connections[crypt_connection_id], 0 ,sizeof(Crypto_Connection));
|
||||
crypto_connections[crypt_connection_id].number = ~0;
|
||||
@ -398,9 +402,9 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre
|
||||
return -1;
|
||||
}*/
|
||||
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
|
||||
if(crypto_connections[i].status == 0) {
|
||||
if(crypto_connections[i].status == CONN_NO_CONNECTION) {
|
||||
crypto_connections[i].number = connection_id;
|
||||
crypto_connections[i].status = 2;
|
||||
crypto_connections[i].status = CONN_NOT_CONFIRMED;
|
||||
random_nonce(crypto_connections[i].recv_nonce);
|
||||
memcpy(crypto_connections[i].sent_nonce, secret_nonce, crypto_box_NONCEBYTES);
|
||||
memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
|
||||
@ -413,9 +417,9 @@ int accept_crypto_inbound(int connection_id, uint8_t *public_key, uint8_t *secre
|
||||
crypto_connections[i].sessionpublic_key) == 1) {
|
||||
increment_nonce(crypto_connections[i].recv_nonce);
|
||||
uint32_t zero = 0;
|
||||
crypto_connections[i].status = 3; /* connection status needs to be 3 for write_cryptpacket() to work */
|
||||
crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */
|
||||
write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero));
|
||||
crypto_connections[i].status = 2; /* set it to its proper value right after. */
|
||||
crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */
|
||||
return i;
|
||||
}
|
||||
return -1; /* this should never happen. */
|
||||
@ -431,7 +435,7 @@ int is_cryptoconnected(int crypt_connection_id)
|
||||
{
|
||||
if (crypt_connection_id >= 0 && crypt_connection_id < MAX_CRYPTO_CONNECTIONS)
|
||||
return crypto_connections[crypt_connection_id].status;
|
||||
return 0;
|
||||
return CONN_NO_CONNECTION;
|
||||
}
|
||||
|
||||
/* Generate our public and private keys
|
||||
@ -490,7 +494,7 @@ static void receive_crypto()
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
|
||||
if (crypto_connections[i].status == 1) {
|
||||
if (crypto_connections[i].status == CONN_HANDSHAKE_SENT) {
|
||||
uint8_t temp_data[MAX_DATA_SIZE];
|
||||
uint8_t secret_nonce[crypto_box_NONCEBYTES];
|
||||
uint8_t public_key[crypto_box_PUBLICKEYBYTES];
|
||||
@ -507,17 +511,17 @@ static void receive_crypto()
|
||||
memcpy(crypto_connections[i].peersessionpublic_key, session_key, crypto_box_PUBLICKEYBYTES);
|
||||
increment_nonce(crypto_connections[i].sent_nonce);
|
||||
uint32_t zero = 0;
|
||||
crypto_connections[i].status = 3; /* connection status needs to be 3 for write_cryptpacket() to work */
|
||||
crypto_connections[i].status = CONN_ESTABLISHED; /* connection status needs to be 3 for write_cryptpacket() to work */
|
||||
write_cryptpacket(i, ((uint8_t *)&zero), sizeof(zero));
|
||||
crypto_connections[i].status = 2; /* set it to its proper value right after. */
|
||||
crypto_connections[i].status = CONN_NOT_CONFIRMED; /* set it to its proper value right after. */
|
||||
}
|
||||
}
|
||||
} else if (id_packet(crypto_connections[i].number) != -1) // This should not happen kill the connection if it does
|
||||
crypto_kill(crypto_connections[i].number);
|
||||
|
||||
}
|
||||
if (crypto_connections[i].status == 2) {
|
||||
if (id_packet(crypto_connections[i].number) == 3) {
|
||||
if (crypto_connections[i].status == CONN_NOT_CONFIRMED) {
|
||||
if (id_packet(crypto_connections[i].number) == CONN_ESTABLISHED) {
|
||||
uint8_t temp_data[MAX_DATA_SIZE];
|
||||
uint8_t data[MAX_DATA_SIZE];
|
||||
int length = read_packet(crypto_connections[i].number, temp_data);
|
||||
@ -527,7 +531,7 @@ static void receive_crypto()
|
||||
uint32_t zero = 0;
|
||||
if (len == sizeof(uint32_t) && memcmp(((uint8_t *)&zero), data, sizeof(uint32_t)) == 0) {
|
||||
increment_nonce(crypto_connections[i].recv_nonce);
|
||||
crypto_connections[i].status = 3;
|
||||
crypto_connections[i].status = CONN_ESTABLISHED;
|
||||
|
||||
/* connection is accepted so we disable the auto kill by setting it to about 1 month from now. */
|
||||
kill_connection_in(crypto_connections[i].number, 3000000);
|
||||
@ -556,8 +560,8 @@ static void killTimedout()
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0; i < MAX_CRYPTO_CONNECTIONS; ++i) {
|
||||
if (crypto_connections[i].status != 0 && is_connected(crypto_connections[i].number) == 4)
|
||||
crypto_connections[i].status = 4;
|
||||
if (crypto_connections[i].status != CONN_NO_CONNECTION && is_connected(crypto_connections[i].number) == 4)
|
||||
crypto_connections[i].status = CONN_TIMED_OUT;
|
||||
else if (is_connected(crypto_connections[i].number) == 4) {
|
||||
kill_connection(crypto_connections[i].number);
|
||||
crypto_connections[i].number = ~0;
|
||||
|
40
docs/CMakeLists.txt
Normal file
40
docs/CMakeLists.txt
Normal file
@ -0,0 +1,40 @@
|
||||
# cmake should not fail if sphinx is missing
|
||||
find_package(Sphinx)
|
||||
|
||||
if(SPHINX_EXECUTABLE)
|
||||
|
||||
if(NOT DEFINED SPHINX_THEME)
|
||||
set(SPHINX_THEME default)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED SPHINX_THEME_DIR)
|
||||
set(SPHINX_THEME_DIR)
|
||||
endif()
|
||||
|
||||
# configured documentation tools and intermediate build results
|
||||
set(BINARY_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/_build")
|
||||
|
||||
# Sphinx cache with pickled ReST documents
|
||||
set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees")
|
||||
|
||||
# HTML output directory
|
||||
set(SPHINX_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/html")
|
||||
|
||||
configure_file(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/conf.py"
|
||||
"${BINARY_BUILD_DIR}/conf.py"
|
||||
@ONLY)
|
||||
|
||||
add_custom_target(docs
|
||||
${SPHINX_EXECUTABLE}
|
||||
-b html
|
||||
-c "${BINARY_BUILD_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
"${SPHINX_HTML_DIR}"
|
||||
COMMENT "Building HTML documentation with Sphinx")
|
||||
else()
|
||||
add_custom_target(docs
|
||||
echo
|
||||
"Please install python-sphinx to build the docs or read the docs online: https://projecttox.readthedocs.org/en/latest"
|
||||
COMMENT "No sphinx executebale found")
|
||||
endif()
|
@ -1,25 +0,0 @@
|
||||
# Tox User Commands
|
||||
Here's a list of commands that nTox accepts,
|
||||
which can all be used by starting your line with
|
||||
a */*. Currently there can be no spaces before this.
|
||||
|
||||
* */f* [ID]
|
||||
+ Add a friend with ID [ID].
|
||||
* */d*
|
||||
+ Call doMessenger() which does...something?
|
||||
* */m* \[FRIEND\_NUM\] \[MESSAGE\]
|
||||
+ Message \[FRIEND\_NUM\] \[MESSAGE\].
|
||||
* */n* \[NAME\]
|
||||
+ Change your username to \[NAME\].
|
||||
* */l*
|
||||
+ Print your list of friends. (like you have any)
|
||||
* */s* \[STATUS\]
|
||||
+ Set your status to \[STATUS\].
|
||||
* */a* \[ID\]
|
||||
+ Accept friend request from \[ID\].
|
||||
* */i*
|
||||
+ Print useful info about your client.
|
||||
* */h*
|
||||
+ Print some help.
|
||||
* */q/*
|
||||
+ Quit Tox. (why ;_;)
|
48
docs/commands.rst
Normal file
48
docs/commands.rst
Normal file
@ -0,0 +1,48 @@
|
||||
Tox User Commands
|
||||
=================
|
||||
|
||||
Here's a list of commands that nTox accepts, which can all be used by
|
||||
starting your line with a */*. Currently there can be no spaces before
|
||||
this.
|
||||
|
||||
- */f* [ID]
|
||||
|
||||
- Add a friend with ID [ID].
|
||||
|
||||
- */d*
|
||||
|
||||
- Call doMessenger() which does...something?
|
||||
|
||||
- */m* [FRIEND\_NUM] [MESSAGE]
|
||||
|
||||
- Message [FRIEND\_NUM] [MESSAGE].
|
||||
|
||||
- */n* [NAME]
|
||||
|
||||
- Change your username to [NAME].
|
||||
|
||||
- */l*
|
||||
|
||||
- Print your list of friends. (like you have any)
|
||||
|
||||
- */s* [STATUS]
|
||||
|
||||
- Set your status to [STATUS].
|
||||
|
||||
- */a* [ID]
|
||||
|
||||
- Accept friend request from [ID].
|
||||
|
||||
- */i*
|
||||
|
||||
- Print useful info about your client.
|
||||
|
||||
- */h*
|
||||
|
||||
- Print some help.
|
||||
|
||||
- */q/*
|
||||
|
||||
- Quit Tox. (why ;\_;)
|
||||
|
||||
|
242
docs/conf.py
Normal file
242
docs/conf.py
Normal file
@ -0,0 +1,242 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# ProjectTox documentation build configuration file, created by
|
||||
# sphinx-quickstart on Wed Jul 31 23:07:35 2013.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
|
||||
import sys, os
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be extensions
|
||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
|
||||
extensions = []
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'ProjectTox'
|
||||
copyright = u'2013, Tox Team'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.1'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.1'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents.
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
#add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
#add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
#modindex_common_prefix = []
|
||||
|
||||
|
||||
# -- Options for HTML output ---------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = 'ProjectToxdoc'
|
||||
|
||||
|
||||
# -- Options for LaTeX output --------------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual]).
|
||||
latex_documents = [
|
||||
('index', 'ProjectTox.tex', u'ProjectTox Documentation',
|
||||
u'Tox Team', 'manual'),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output --------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
('index', 'projecttox', u'ProjectTox Documentation',
|
||||
[u'Tox Team'], 1)
|
||||
]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output ------------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
('index', 'ProjectTox', u'ProjectTox Documentation',
|
||||
u'Tox Team', 'ProjectTox', 'One line description of project.',
|
||||
'Miscellaneous'),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
25
docs/index.rst
Normal file
25
docs/index.rst
Normal file
@ -0,0 +1,25 @@
|
||||
.. ProjectTox documentation master file, created by
|
||||
sphinx-quickstart on Wed Jul 31 23:07:35 2013.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to ProjectTox's documentation!
|
||||
======================================
|
||||
|
||||
Contents:
|
||||
|
||||
.. toctree::
|
||||
start_guide.rst
|
||||
install.rst
|
||||
commands.rst
|
||||
:maxdepth: 2
|
||||
|
||||
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
||||
* :ref:`genindex`
|
||||
* :ref:`modindex`
|
||||
* :ref:`search`
|
||||
|
129
docs/install.rst
Normal file
129
docs/install.rst
Normal file
@ -0,0 +1,129 @@
|
||||
Install Instructions
|
||||
====================
|
||||
|
||||
Linux
|
||||
---------
|
||||
|
||||
First, install the build dependencies ::
|
||||
|
||||
bash apt-get install build-essential libtool autotools-dev automake libconfig-dev ncurses-dev cmake checkinstall
|
||||
|
||||
.. note :: ``libconfig-dev`` should be >= 1.4.
|
||||
|
||||
|
||||
Then you'll need a recent version of `libsodium <https://github.com/jedisct1/libsodium>`_ ::
|
||||
|
||||
git clone git://github.com/jedisct1/libsodium.git
|
||||
cd libsodium
|
||||
git checkout tags/0.4.2
|
||||
./autogen.sh
|
||||
./configure && make check
|
||||
sudo checkinstall --install --pkgname libsodium --pkgversion 0.4.2 --nodoc
|
||||
sudo ldconfig``
|
||||
|
||||
Finally, fetch the Tox source code and run cmake ::
|
||||
|
||||
git clone git://github.com/irungentoo/ProjectTox-Core.git
|
||||
cd ProjectTox-Core && mkdir build && cd build
|
||||
cmake ..
|
||||
|
||||
Then you can build any of the files in `/testing`_ and `/other`_ that are currently
|
||||
supported on your platform by running ::
|
||||
|
||||
make name_of_c_file
|
||||
|
||||
For example, to build `Messenger_test.c`_ you would run ::
|
||||
|
||||
make Messenger_test
|
||||
|
||||
|
||||
Or you could just build everything that is supported on your platform by
|
||||
running ::
|
||||
bash make
|
||||
|
||||
OS X
|
||||
------
|
||||
|
||||
Homebrew
|
||||
~~~~~~~~~~
|
||||
::
|
||||
|
||||
brew install libtool automake autoconf libconfig libsodium cmake
|
||||
cmake .
|
||||
make
|
||||
sudo make install
|
||||
|
||||
Non-homebrew
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Much the same as Linux, remember to install the latest XCode and the
|
||||
developer tools (Preferences -> Downloads -> Command Line Tools). Users
|
||||
running Mountain Lion and the latest version of XCode (4.6.3) will also
|
||||
need to install libtool, automake and autoconf. They are easy enough to
|
||||
install, grab them from http://www.gnu.org/software/libtool/,
|
||||
http://www.gnu.org/software/autoconf/ and
|
||||
http://www.gnu.org/software/automake/, then follow these steps for each:
|
||||
|
||||
::
|
||||
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
|
||||
Do not install them from macports (or any dependencies for that matter)
|
||||
as they get shoved in the wrong directory and make your life more
|
||||
annoying.
|
||||
|
||||
Another thing you may want to install is the latest gcc, this caused me
|
||||
a few problems as XCode from 4.3 no longer includes gcc and instead uses
|
||||
LLVM-GCC, a nice install guide can be found at
|
||||
http://caiustheory.com/install-gcc-421-apple-build-56663-with-xcode-42
|
||||
|
||||
Windows
|
||||
---------
|
||||
|
||||
You should install:
|
||||
|
||||
* `MinGW <http://sourceforge.net/projects/mingw/>`_'s C compiler
|
||||
* `CMake <http://www.cmake.org/cmake/resources/software.html>`_
|
||||
|
||||
You have to `modify your PATH environment
|
||||
variable <http://www.computerhope.com/issues/ch000549.htm>`_ so that it
|
||||
contains MinGW's bin folder path. With default settings, the bin folder
|
||||
is located at ``C:\MinGW\bin``, which means that you would have to
|
||||
append ``;C:\MinGW\bin`` to the PATH variable.
|
||||
|
||||
Then you should either clone this repo by using git, or just download a
|
||||
`zip of current Master
|
||||
branch <https://github.com/irungentoo/ProjectTox-Core/archive/master.zip>`_
|
||||
and extract it somewhere.
|
||||
|
||||
After that you should get precompiled package of libsodium from
|
||||
`here <https://download.libsodium.org/libsodium/releases/libsodium-win32-0.4.2.tar.gz>`_
|
||||
and extract the archive into this repo's root. That is, ``sodium``
|
||||
folder should be along with ``core``, ``testing`` and other folders.
|
||||
|
||||
Navigate in ``cmd`` to this repo and run::
|
||||
|
||||
mkdir build && cd build
|
||||
cmake -G "MinGW Makefiles" ..
|
||||
|
||||
Then you can build any of the `/testing`_ and `/other`_ that are currently
|
||||
supported on your platform by running::
|
||||
|
||||
mingw32-make name_of_c_file
|
||||
|
||||
For example, to build `Messenger_test.c`_ you would run::
|
||||
|
||||
mingw32-make Messenger_test``
|
||||
|
||||
Or you could just build everything that is supported on your platform by
|
||||
running::
|
||||
|
||||
mingw32-make
|
||||
|
||||
|
||||
.. _/testing: https://github.com/irungentoo/ProjectTox-Core/tree/master/testing
|
||||
.. _/other: https://github.com/irungentoo/ProjectTox-Core/tree/master/other
|
||||
|
||||
.. _Messenger_test.c: https://github.com/irungentoo/ProjectTox-Core/tree/master/other/Messanger_test.c
|
@ -1,40 +0,0 @@
|
||||
# Tox nutzen
|
||||
1. Tox erstellen
|
||||
2. Fehler korrigieren
|
||||
3. Im IRC nach Hilfe fragen
|
||||
4. Auf Debug-Reise für Entwickler
|
||||
5. Tox wirklich erstellen
|
||||
6. ???
|
||||
|
||||
Trotz der ganzen Arbeit, die wir bisher in Tox
|
||||
gesteckt haben, gibt es noch keine richtige
|
||||
Anleitung, wie man Tox _benutzt_.
|
||||
Dies ist ein anwenderfreundlicher Versuch.
|
||||
|
||||
1. Verbinde dich zum Netzwerk!
|
||||
+ Du musst dich zu einem Bootstrap-Server verbinden, um einen öffentlichen Schlüssel zu erhalten.
|
||||
+ Wo finde ich einen öffentlichen Server? Zur Zeit hier:
|
||||
(die Hilfe-Nachricht von nTox ohne Kommandos hilft auch)
|
||||
+ 198.46.136.167 33445 728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854
|
||||
+ 192.81.133.111 33445 8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858
|
||||
+ 66.175.223.88 33445 AC4112C975240CAD260BB2FCD134266521FAAF0A5D159C5FD3201196191E4F5D
|
||||
+ 192.184.81.118 33445 5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143
|
||||
2. Finde einen Freund!
|
||||
+ Jetzt, da du im Netzwerk bist, brauchst du einen Freund. Um einen zu bekommen,
|
||||
musst du eine Anfrage senden oder erhalten. Was eine Anfrage ist?
|
||||
Es ist wie eine Freundschaftsanfrage, jedoch benutzen wir unglaublich schaurige
|
||||
und kryptische Nummern anstatt Namen. When nTox startet, erscheint _deine_ lange,
|
||||
schaurige Nummer, auch *öffentlicher Schlüssel* genannt. Diesen kannst du an
|
||||
andere Personen weitergeben und sie können dich als "Freund" hinzufügen. Oder du
|
||||
fügst andere Personen mit dem */f*-Befehl hinzu, wenn du möchtest.
|
||||
3. Chatte drauf los!
|
||||
+ Benutze nun den */m*-Befehl, um eine Nachricht an jemanden zu senden. Wow, du chattest!
|
||||
4. Mach etwas kaputt!
|
||||
+ Jep, pre-alpha-alpha-Software stürzt manchmal ab. Wir arbeiten daran.
|
||||
+ Bitte melde alle Abstürze entweder an die GitHub-Seite oder #tox-dev im freenode-IRC.
|
||||
5. Nichts ist kaputt, aber was bedeutet */f*?
|
||||
+ nTox liest einen Text als Befehl, wenn das erste Zeichen ein Schrägstrich ist ('/').
|
||||
Du kannst alle Befehle in commands.md nachlesen.
|
||||
6. Benutze und unterstütze Tox!
|
||||
+ Programmiere, debugge, dokumentiere, übersetze für uns, oder sprich einfach über uns!
|
||||
+ Je mehr Interesse wir erhalten, desto mehr Arbeit wird getan und desto besser wird Tox.
|
66
docs/start_guide.de.rst
Normal file
66
docs/start_guide.de.rst
Normal file
@ -0,0 +1,66 @@
|
||||
Tox nutzen
|
||||
==========
|
||||
|
||||
1. :doc:`Tox erstellen <install>`
|
||||
2. Fehler korrigieren
|
||||
3. Im IRC nach Hilfe fragen
|
||||
4. Auf Debug-Reise für Entwickler
|
||||
5. Tox wirklich erstellen
|
||||
6. ???
|
||||
|
||||
Trotz der ganzen Arbeit, die wir bisher in Tox gesteckt haben, gibt es
|
||||
noch keine richtige Anleitung, wie man Tox *benutzt*. Dies ist ein
|
||||
anwenderfreundlicher Versuch.
|
||||
|
||||
1. Verbinde dich zum Netzwerk!
|
||||
|
||||
- Du musst dich zu einem Bootstrap-Server verbinden, um einen
|
||||
öffentlichen Schlüssel zu erhalten.
|
||||
- Wo finde ich einen öffentlichen Server? Zur Zeit hier: (die
|
||||
Hilfe-Nachricht von nTox ohne Kommandos hilft auch)
|
||||
|
||||
- 198.46.136.167 33445
|
||||
728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854
|
||||
- 192.81.133.111 33445
|
||||
8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858
|
||||
- 66.175.223.88 33445
|
||||
AC4112C975240CAD260BB2FCD134266521FAAF0A5D159C5FD3201196191E4F5D
|
||||
- 192.184.81.118 33445
|
||||
5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143
|
||||
|
||||
2. Finde einen Freund!
|
||||
|
||||
- Jetzt, da du im Netzwerk bist, brauchst du einen Freund. Um einen
|
||||
zu bekommen, musst du eine Anfrage senden oder erhalten. Was eine
|
||||
Anfrage ist? Es ist wie eine Freundschaftsanfrage, jedoch benutzen
|
||||
wir unglaublich schaurige und kryptische Nummern anstatt Namen.
|
||||
When nTox startet, erscheint *deine* lange, schaurige Nummer, auch
|
||||
*öffentlicher Schlüssel* genannt. Diesen kannst du an andere
|
||||
Personen weitergeben und sie können dich als "Freund" hinzufügen.
|
||||
Oder du fügst andere Personen mit dem */f*-Befehl hinzu, wenn du
|
||||
möchtest.
|
||||
|
||||
3. Chatte drauf los!
|
||||
|
||||
- Benutze nun den */m*-Befehl, um eine Nachricht an jemanden zu
|
||||
senden. Wow, du chattest!
|
||||
|
||||
4. Mach etwas kaputt!
|
||||
|
||||
- Jep, pre-alpha-alpha-Software stürzt manchmal ab. Wir arbeiten
|
||||
daran.
|
||||
- Bitte melde alle Abstürze entweder an die GitHub-Seite oder
|
||||
#tox-dev im freenode-IRC.
|
||||
|
||||
5. Nichts ist kaputt, aber was bedeutet */f*?
|
||||
|
||||
- nTox liest einen Text als Befehl, wenn das erste Zeichen ein
|
||||
Schrägstrich ist ('/'). Du kannst alle Befehle in commands.md
|
||||
nachlesen.
|
||||
|
||||
6. Benutze und unterstütze Tox!
|
||||
|
||||
- Programmiere, debugge, dokumentiere, übersetze für uns, oder
|
||||
sprich einfach über uns!
|
||||
- Je mehr Interesse wir erhalten, desto mehr Arbeit wird getan und
|
||||
desto besser wird Tox.
|
@ -1,38 +0,0 @@
|
||||
# Using Tox
|
||||
1. [Build Tox](../INSTALL.md)
|
||||
2. Fix errors
|
||||
3. Consult IRC for help
|
||||
4. Go on debugging journey for devs
|
||||
5. Build Tox for real
|
||||
6. ???
|
||||
|
||||
For all the work we've put into Tox so far,
|
||||
there isn't yet a decent guide for how you _use_
|
||||
Tox. Here's a user-friendly attempt at it.
|
||||
|
||||
1. Connect to the network!
|
||||
+ You need to connect to a bootstrapping server, to give you a public key.
|
||||
+ Where can I find a public server? Right here, as of now:
|
||||
(the help message from running `nTox` with no args will help)
|
||||
+ `198.46.136.167 33445 728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854`
|
||||
+ `192.81.133.111 33445 8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858`
|
||||
+ `66.175.223.88 33445 AC4112C975240CAD260BB2FCD134266521FAAF0A5D159C5FD3201196191E4F5D`
|
||||
+ `192.184.81.118 33445 5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143`
|
||||
2. Find a friend!
|
||||
+ Now that you're on the network, you need a friend. To get one of those,
|
||||
you need to to send or receive a request. What's a request, you ask?
|
||||
It's like a friend request, but we use really scary and cryptic numbers
|
||||
instead of names. When `nTox` starts, it shows _your_ long, scary number,
|
||||
called your *public key*. Give that to people, and they can add you as
|
||||
a "friend". Or, you can add someone else, with the `/f` command, if you like.
|
||||
3. Chat it up!
|
||||
+ Now use the `/m` command to send a message to someone. Wow, you're chatting!
|
||||
4. But something broke!
|
||||
+ Yeah, pre-alpha-alpha software tends to do that. We're working on it.
|
||||
+ Please report all crashes to either the GitHub page, or `#tox-dev` on freenode.
|
||||
5. Nothing broke, but what does `/f` mean?
|
||||
+ `nTox` parses text as a command if the first character is a forward-slash (`/`).
|
||||
You can check all commands in commands.md.
|
||||
6. Use and support Tox!
|
||||
+ Code for us, debug for us, document for us, translate for us, even just talk about us!
|
||||
+ The more interest we get, the more work gets done, the better Tox is.
|
63
docs/start_guide.rst
Normal file
63
docs/start_guide.rst
Normal file
@ -0,0 +1,63 @@
|
||||
Using Tox
|
||||
=========
|
||||
|
||||
.. note:: There is a German version of this page available: :doc:`start_guide.de`
|
||||
|
||||
|
||||
1. :doc:`Build Tox <install>`
|
||||
2. Fix errors
|
||||
3. Consult IRC for help
|
||||
4. Go on debugging journey for devs
|
||||
5. Build Tox for real
|
||||
6. ???
|
||||
|
||||
For all the work we've put into Tox so far, there isn't yet a decent
|
||||
guide for how you *use* Tox. Here's a user-friendly attempt at it.
|
||||
|
||||
1. Connect to the network!
|
||||
|
||||
- You need to connect to a bootstrapping server, to give you a
|
||||
public key.
|
||||
- Where can I find a public server? Right here, as of now: (the help
|
||||
message from running ``nTox`` with no args will help)
|
||||
|
||||
- ``198.46.136.167 33445 728925473812C7AAC482BE7250BCCAD0B8CB9F737BF3D42ABD34459C1768F854``
|
||||
- ``192.81.133.111 33445 8CD5A9BF0A6CE358BA36F7A653F99FA6B258FF756E490F52C1F98CC420F78858``
|
||||
- ``66.175.223.88 33445 AC4112C975240CAD260BB2FCD134266521FAAF0A5D159C5FD3201196191E4F5D``
|
||||
- ``192.184.81.118 33445 5CD7EB176C19A2FD840406CD56177BB8E75587BB366F7BB3004B19E3EDC04143``
|
||||
|
||||
2. Find a friend!
|
||||
|
||||
- Now that you're on the network, you need a friend. To get one of
|
||||
those, you need to to send or receive a request. What's a request,
|
||||
you ask? It's like a friend request, but we use really scary and
|
||||
cryptic numbers instead of names. When ``nTox`` starts, it shows
|
||||
*your* long, scary number, called your *public key*. Give that to
|
||||
people, and they can add you as a "friend". Or, you can add
|
||||
someone else, with the ``/f`` command, if you like.
|
||||
|
||||
3. Chat it up!
|
||||
|
||||
- Now use the ``/m`` command to send a message to someone. Wow,
|
||||
you're chatting!
|
||||
|
||||
4. But something broke!
|
||||
|
||||
- Yeah, pre-alpha-alpha software tends to do that. We're working on
|
||||
it.
|
||||
- Please report all crashes to either the GitHub page, or
|
||||
``#tox-dev`` on freenode.
|
||||
|
||||
5. Nothing broke, but what does ``/f`` mean?
|
||||
|
||||
- ``nTox`` parses text as a command if the first character is a
|
||||
forward-slash (``/``). You can check all commands in commands.md.
|
||||
|
||||
6. Use and support Tox!
|
||||
|
||||
- Code for us, debug for us, document for us, translate for us, even
|
||||
just talk about us!
|
||||
- The more interest we get, the more work gets done, the better Tox
|
||||
is.
|
||||
|
||||
|
@ -89,7 +89,12 @@ char *format_message(char *message, int friendnum)
|
||||
char* time = asctime(timeinfo);
|
||||
size_t len = strlen(time);
|
||||
time[len-1] = '\0';
|
||||
sprintf(msg, "[%d] %s <%s> %s", friendnum, time, name, message); // timestamp
|
||||
if (friendnum != -1) {
|
||||
sprintf(msg, "[%d] %s <%s> %s", friendnum, time, name, message);
|
||||
} else {
|
||||
// This message came from ourselves
|
||||
sprintf(msg, "%s <%s> %s", time, name, message);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
@ -106,24 +111,28 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
|
||||
char temp_id[128];
|
||||
for (i = 0; i < 128; i++)
|
||||
temp_id[i] = line[i+prompt_offset];
|
||||
|
||||
int num = m_addfriend(hex_string_to_bin(temp_id), (uint8_t*)"Install Gentoo", sizeof("Install Gentoo"));
|
||||
char numstring[100];
|
||||
switch (num) {
|
||||
case -1:
|
||||
sprintf(numstring, "[i] Incorrect key length");
|
||||
break;
|
||||
case -2:
|
||||
sprintf(numstring, "[i] That appears to be your own key");
|
||||
break;
|
||||
case -3:
|
||||
sprintf(numstring, "[i] Friend request already sent");
|
||||
break;
|
||||
case -4:
|
||||
sprintf(numstring, "[i] Could not add friend");
|
||||
break;
|
||||
default:
|
||||
sprintf(numstring, "[i] Added friend %d", num);
|
||||
break;
|
||||
case -1:
|
||||
sprintf(numstring, "[i] Message is too long.");
|
||||
break;
|
||||
case -2:
|
||||
sprintf(numstring, "[i] Please add a message to your request.");
|
||||
break;
|
||||
case -3:
|
||||
sprintf(numstring, "[i] That appears to be your own ID.");
|
||||
break;
|
||||
case -4:
|
||||
sprintf(numstring, "[i] Friend request already sent.");
|
||||
break;
|
||||
case -5:
|
||||
sprintf(numstring, "[i] Undefined error when adding friend.");
|
||||
break;
|
||||
default:
|
||||
sprintf(numstring, "[i] Added friend as %d.", num);
|
||||
break;
|
||||
}
|
||||
new_lines(numstring);
|
||||
do_refresh();
|
||||
@ -133,6 +142,9 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
|
||||
}
|
||||
else if (inpt_command == 'm') { //message command: /m friendnumber messsage
|
||||
size_t len = strlen(line);
|
||||
if(len < 3)
|
||||
return;
|
||||
|
||||
char numstring[len-3];
|
||||
char message[len-3];
|
||||
int i;
|
||||
@ -141,13 +153,13 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
|
||||
numstring[i] = line[i+3];
|
||||
} else {
|
||||
int j;
|
||||
for (j = (i+1); j < len; j++)
|
||||
for (j = (i+1); j < (len+1); j++)
|
||||
message[j-i-1] = line[j+3];
|
||||
break;
|
||||
}
|
||||
}
|
||||
int num = atoi(numstring);
|
||||
if (m_sendmessage(num, (uint8_t*) message, sizeof(message)) != 1) {
|
||||
if (m_sendmessage(num, (uint8_t*) message, strlen(message) + 1) != 1) {
|
||||
new_lines("[i] could not send message");
|
||||
} else {
|
||||
new_lines(format_message(message, -1));
|
||||
@ -162,7 +174,7 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
|
||||
name[i-3] = line[i];
|
||||
}
|
||||
name[i-3] = 0;
|
||||
setname(name, i);
|
||||
setname(name, i - 2);
|
||||
char numstring[100];
|
||||
sprintf(numstring, "[i] changed nick to %s", (char*)name);
|
||||
new_lines(numstring);
|
||||
@ -179,7 +191,7 @@ void line_eval(char lines[HISTORY][STRING_LENGTH], char *line)
|
||||
status[i-3] = line[i];
|
||||
}
|
||||
status[i-3] = 0;
|
||||
m_set_userstatus(status, strlen((char*)status));
|
||||
m_set_userstatus(status, strlen((char*)status) + 1);
|
||||
char numstring[100];
|
||||
sprintf(numstring, "[i] changed status to %s", (char*)status);
|
||||
new_lines(numstring);
|
||||
@ -313,17 +325,6 @@ void print_request(uint8_t *public_key, uint8_t *data, uint16_t length)
|
||||
|
||||
void print_message(int friendnumber, uint8_t * string, uint16_t length)
|
||||
{
|
||||
char name[MAX_NAME_LENGTH];
|
||||
getname(friendnumber, (uint8_t*)name);
|
||||
char msg[100+length+strlen(name)+1];
|
||||
time_t rawtime;
|
||||
struct tm * timeinfo;
|
||||
time ( &rawtime );
|
||||
timeinfo = localtime ( &rawtime );
|
||||
char* temp = asctime(timeinfo);
|
||||
size_t len = strlen(temp);
|
||||
temp[len-1] = '\0';
|
||||
sprintf(msg, "[%d] %s <%s> %s", friendnumber, temp, name, string); // timestamp
|
||||
new_lines(format_message((char*)string, friendnumber));
|
||||
}
|
||||
|
||||
|
@ -132,13 +132,15 @@ void line_eval(char* line)
|
||||
printf(numstring);
|
||||
}
|
||||
else if (num == -1)
|
||||
printf("\nWrong key size\n\n");
|
||||
printf("\n[i] Message is too long.\n\n");
|
||||
else if (num == -2)
|
||||
printf("\nYou can't add yourself\n\n");
|
||||
printf("\n[i] Please add a message to your friend request.\n\n");
|
||||
else if (num == -3)
|
||||
printf("\nYou already have this person added\n\n");
|
||||
printf("\n[i] That appears to be your own ID.\n\n");
|
||||
else if (num == -4)
|
||||
printf("\nUndefined error when adding friend");
|
||||
printf("\n[i] Friend request already sent.\n\n");
|
||||
else if (num == -5)
|
||||
printf("\n[i] Undefined error when adding friend\n\n");
|
||||
}
|
||||
|
||||
else if (inpt_command == 'r') {
|
||||
|
@ -280,6 +280,26 @@ void prepare_window(WINDOW* w) {
|
||||
wresize(w, LINES-2, COLS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Draws cursor relative to input on prompt window.
|
||||
* Removes cursor on friends window and chat windows.
|
||||
*
|
||||
* TODO: Make it work for chat windows
|
||||
*/
|
||||
void position_cursor(WINDOW* w, char* title)
|
||||
{
|
||||
curs_set(1);
|
||||
if (strcmp(title, "[prompt]") == 0) { // main/prompt window
|
||||
int x, y;
|
||||
getyx(w, y, x);
|
||||
move(y, x);
|
||||
}
|
||||
else if (strcmp(title, "[friends]") == 0) // friends window
|
||||
curs_set(0);
|
||||
else // any other window (i.e chat)
|
||||
curs_set(0);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
int ch;
|
||||
ToxWindow* a;
|
||||
@ -299,6 +319,7 @@ int main(int argc, char* argv[]) {
|
||||
a->blink = false;
|
||||
a->onDraw(a);
|
||||
draw_bar();
|
||||
position_cursor(a->window, a->title);
|
||||
|
||||
// Handle input.
|
||||
ch = getch();
|
||||
|
@ -134,10 +134,28 @@ static void execute(ToxWindow* self, char* cmd) {
|
||||
}
|
||||
|
||||
num = m_addfriend(id_bin, (uint8_t*) msg, strlen(msg)+1);
|
||||
|
||||
wprintw(self->window, "Friend added as %d.\n", num);
|
||||
on_friendadded(num);
|
||||
switch (num) {
|
||||
case -1:
|
||||
wprintw(self->window, "Message is too long.\n");
|
||||
break;
|
||||
case -2:
|
||||
wprintw(self->window, "Please add a message to your request.\n");
|
||||
case -3:
|
||||
wprintw(self->window, "That appears to be your own ID.\n");
|
||||
break;
|
||||
case -4:
|
||||
wprintw(self->window, "Friend request already sent.\n");
|
||||
break;
|
||||
case -5:
|
||||
wprintw(self->window, "[i] Undefined error when adding friend.\n");
|
||||
break;
|
||||
default:
|
||||
wprintw(self->window, "Friend added as %d.\n", num);
|
||||
on_friendadded(num);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else if(!strcmp(cmd, "help")) {
|
||||
print_usage(self);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user