Fixed conflicts

This commit is contained in:
mannol 2014-07-21 04:10:05 +02:00
commit 79115259a8
28 changed files with 739 additions and 177 deletions

View File

@ -150,6 +150,14 @@ Grab the following packages:
* https://gnu.org/software/automake/
* https://github.com/jedisct1/libsodium
* http://check.sourceforge.net/
* http://yasm.tortall.net/Download.html
* https://code.google.com/p/webm/downloads/list
* http://www.opus-codec.org/downloads/
* http://www.freedesktop.org/wiki/Software/pkg-config/
You must install yasm before installing libvpx, otherwise libvpx will fail to make correctly.
pkg-config is important for enabling a/v support in tox core, failure to install pkg-config will prevent tox core form finding the required libopus/libvpx libraries. (pkg-config may not configure properly, if you get an error about GLIB, run configure with the following parameter, --with-internal-glib).
Uncompress and install them all. Make sure to follow the README as the instructions change, but they all follow the same pattern below:
@ -159,9 +167,8 @@ make
sudo make install
```
In your local TOX repository:
Compiling and installing Tox Core
Then generate makefile, build and install tox:
```bash
cd ProjectTox-Core
autoreconf -i
@ -170,12 +177,17 @@ make
make install
```
Do not install them from macports (or any dependencies for that matter) as they get shoved in the wrong directory
(or the wrong version gets installed) and make your life more annoying.
If after running ./configure you get an error about core being unable to find libsodium (and you have installed it) run the following in place of ./configure;
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
./configure --with-libsodium-headers=/usr/local/include/ --with-libsodium-libs=/usr/local/lib
Ensure you set the locations correctly depending on where you installed libsodium on your computer.
If there is a problem with opus (for A/V) and you don't get a libtoxav, then try to set the pkg-config environment variable beforehand:
```
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
```
<a name="windows" />
###Windows:

View File

@ -3,7 +3,7 @@
With the rise of governmental monitoring programs, Tox, a FOSS initiative, aims to be an easy to use, all-in-one communication platform that ensures their users full privacy and secure message delivery.<br /> <br />
[**Website**](https://tox.im) **|** [**Wiki**](https://wiki.tox.im/) **|** [**Blog**](https://blog.libtoxcore.so/) **|** [**FAQ**](http://wiki.tox.im/FAQ) **|** [**Binaries**](https://wiki.tox.im/Binaries) **|** [**Clients**](https://wiki.tox.im/Client) **|** [**Compiling**](https://wiki.tox.im/Installing) **|** [**API**](https://libtoxcore.so/) **|** **IRC:** #tox@freenode
[**Website**](https://tox.im) **|** [**Download**](https://wiki.tox.im/Binaries) **|** [**Wiki**](https://wiki.tox.im/) **|** [**Blog**](https://blog.libtoxcore.so/) **|** [**FAQ**](http://wiki.tox.im/FAQ) **|** [**Binaries**](https://wiki.tox.im/Binaries) **|** [**Clients**](https://wiki.tox.im/Client) **|** [**Compiling**](https://wiki.tox.im/Installing) **|** [**API**](https://libtoxcore.so/) **|** **IRC:** #tox@freenode
## The Complex Stuff:
@ -33,7 +33,7 @@ The goal of this project is to create a configuration-free P2P Skype replacement
## Documentation:
- [Installation](/INSTALL.md)
- [Compiling](/INSTALL.md)
- [DHT Protocol](https://wiki.tox.im/index.php/DHT)<br />
- [Lossless UDP Protocol](https://wiki.tox.im/index.php/Lossless_UDP)<br />
- [Crypto](https://wiki.tox.im/index.php/Crypto)<br />

View File

@ -171,6 +171,8 @@ void register_callbacks(ToxAv* av, void* data)
toxav_register_audio_recv_callback(av, callback_audio);
toxav_register_video_recv_callback(av, callback_video);
}
/*************************************************************************************************/
/* Alice calls bob and the call starts.

View File

@ -127,7 +127,6 @@ static void callback_audio(ToxAv *av, int32_t call_index, int16_t *data, int len
static void callback_video(ToxAv *av, int32_t call_index, vpx_image_t *img)
{
}
void register_callbacks(ToxAv* av, void* data)
{
toxav_register_callstate_callback(av, callback_call_started, av_OnStart, data);

View File

@ -200,6 +200,25 @@ AC_ARG_ENABLE([testing],
]
)
AC_ARG_ENABLE([[epoll]],
[AS_HELP_STRING([[--enable-epoll[=ARG]]], [enable epoll support (yes, no, auto) [auto]])],
[enable_epoll=${enableval}],
[enable_epoll='auto']
)
if test "$enable_epoll" != "no"; then
AX_HAVE_EPOLL
if test "${ax_cv_have_epoll}" = "yes"; then
AC_DEFINE([TCP_SERVER_USE_EPOLL],[1],[define to 1 to enable epoll support])
enable_epoll='yes'
else
if test "$enable_epoll" = "yes"; then
AC_MSG_ERROR([[Support for epoll was explicitly requested but cannot be enabled on this platform.]])
fi
enable_epoll='no'
fi
fi
DEPSEARCH=
LIBSODIUM_SEARCH_HEADERS=
LIBSODIUM_SEARCH_LIBS=
@ -643,7 +662,7 @@ fi
if test "x$WIN32" = "xyes"; then
AC_CHECK_LIB(ws2_32, main,
[
WINSOCK2_LIBS="-lws2_32"
WINSOCK2_LIBS="-liphlpapi -lws2_32"
AC_SUBST(WINSOCK2_LIBS)
],
[

View File

@ -52,7 +52,7 @@ blocks UDP (or is just unpunchable) (docs/TCP_Network.txt)
See: (https://github.com/jencka/ProjectTox-libtoxdata)
[IN PROGRESS] GUI (no official one chosen yet, a list of promising ones follows)
https://github.com/notsecure/wintox
https://github.com/notsecure/uTox
https://github.com/naxuroqa/Venom
https://github.com/Impyy/Toxy
https://github.com/lehitoskin/blight

104
m4/ax_have_epoll.m4 Normal file
View File

@ -0,0 +1,104 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_have_epoll.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_HAVE_EPOLL([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# AX_HAVE_EPOLL_PWAIT([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
#
# DESCRIPTION
#
# This macro determines whether the system supports the epoll I/O event
# interface. A neat usage example would be:
#
# AX_HAVE_EPOLL(
# [AX_CONFIG_FEATURE_ENABLE(epoll)],
# [AX_CONFIG_FEATURE_DISABLE(epoll)])
# AX_CONFIG_FEATURE(
# [epoll], [This platform supports epoll(7)],
# [HAVE_EPOLL], [This platform supports epoll(7).])
#
# The epoll interface was added to the Linux kernel in version 2.5.45, and
# the macro verifies that a kernel newer than this is installed. This
# check is somewhat unreliable if <linux/version.h> doesn't match the
# running kernel, but it is necessary regardless, because glibc comes with
# stubs for the epoll_create(), epoll_wait(), etc. that allow programs to
# compile and link even if the kernel is too old; the problem would then
# be detected only at runtime.
#
# Linux kernel version 2.6.19 adds the epoll_pwait() call in addition to
# epoll_wait(). The availability of that function can be tested with the
# second macro. Generally speaking, it is safe to assume that
# AX_HAVE_EPOLL would succeed if AX_HAVE_EPOLL_PWAIT has, but not the
# other way round.
#
# LICENSE
#
# Copyright (c) 2008 Peter Simons <simons@cryp.to>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 10
AC_DEFUN([AX_HAVE_EPOLL], [dnl
ax_have_epoll_cppflags="${CPPFLAGS}"
AC_CHECK_HEADER([linux/version.h], [CPPFLAGS="${CPPFLAGS} -DHAVE_LINUX_VERSION_H"])
AC_MSG_CHECKING([for Linux epoll(7) interface])
AC_CACHE_VAL([ax_cv_have_epoll], [dnl
AC_LINK_IFELSE([dnl
AC_LANG_PROGRAM([dnl
#include <sys/epoll.h>
#ifdef HAVE_LINUX_VERSION_H
# include <linux/version.h>
# if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,45)
# error linux kernel version is too old to have epoll
# endif
#endif
], [dnl
int fd, rc;
struct epoll_event ev;
fd = epoll_create(128);
rc = epoll_wait(fd, &ev, 1, 0);])],
[ax_cv_have_epoll=yes],
[ax_cv_have_epoll=no])])
CPPFLAGS="${ax_have_epoll_cppflags}"
AS_IF([test "${ax_cv_have_epoll}" = "yes"],
[AC_MSG_RESULT([yes])
$1],[AC_MSG_RESULT([no])
$2])
])dnl
AC_DEFUN([AX_HAVE_EPOLL_PWAIT], [dnl
ax_have_epoll_cppflags="${CPPFLAGS}"
AC_CHECK_HEADER([linux/version.h],
[CPPFLAGS="${CPPFLAGS} -DHAVE_LINUX_VERSION_H"])
AC_MSG_CHECKING([for Linux epoll(7) interface with signals extension])
AC_CACHE_VAL([ax_cv_have_epoll_pwait], [dnl
AC_LINK_IFELSE([dnl
AC_LANG_PROGRAM([dnl
#ifdef HAVE_LINUX_VERSION_H
# include <linux/version.h>
# if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
# error linux kernel version is too old to have epoll_pwait
# endif
#endif
#include <sys/epoll.h>
#include <signal.h>
], [dnl
int fd, rc;
struct epoll_event ev;
fd = epoll_create(128);
rc = epoll_wait(fd, &ev, 1, 0);
rc = epoll_pwait(fd, &ev, 1, 0, (sigset_t const *)(0));])],
[ax_cv_have_epoll_pwait=yes],
[ax_cv_have_epoll_pwait=no])])
CPPFLAGS="${ax_have_epoll_cppflags}"
AS_IF([test "${ax_cv_have_epoll_pwait}" = "yes"],
[AC_MSG_RESULT([yes])
$1],[AC_MSG_RESULT([no])
$2])
])dnl

View File

@ -0,0 +1,98 @@
#!/usr/bin/env python
"""
Copyright (c) 2014 by nurupo <nurupo.contributions@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""
from socket import *
import sys
if sys.version_info[0] == 2:
print("This script requires Python 3+ in order to run.")
sys.exit(1)
def printHelp():
print("Usage: " + sys.argv[0] + " <ipv4|ipv6> <ip/hostname> <port>")
print(" Example: " + sys.argv[0] + " ipv4 192.210.149.121 33445")
print(" Example: " + sys.argv[0] + " ipv4 23.226.230.47 33445")
print(" Example: " + sys.argv[0] + " ipv4 biribiri.org 33445")
print(" Example: " + sys.argv[0] + " ipv4 cerberus.zodiaclabs.org 33445")
print(" Example: " + sys.argv[0] + " ipv6 2604:180:1::3ded:b280 33445")
print("")
print("Return values:")
print(" 0 - received info reply from a node")
print(" 1 - incorrect command line arguments")
print(" 2 - didn't receive any reply from a node")
print(" 3 - received a malformed/unexpected reply")
if len(sys.argv) != 4:
printHelp()
sys.exit(1)
protocol = sys.argv[1]
ip = sys.argv[2]
port = int(sys.argv[3])
INFO_PACKET_ID = b"\xF0" # https://github.com/irungentoo/toxcore/blob/4940c4c62b6014d1f0586aa6aca7bf6e4ecfcf29/toxcore/network.h#L128
INFO_REQUEST_PACKET_LENGTH = 78 # https://github.com/irungentoo/toxcore/blob/881b2d900d1998981fb6b9938ec66012d049635f/other/bootstrap_node_packets.c#L28
# first byte is INFO_REQUEST_ID, other bytes don't matter as long as reqest's length matches INFO_REQUEST_LENGTH
INFO_REQUEST_PACKET = INFO_PACKET_ID + ( b"0" * (INFO_REQUEST_PACKET_LENGTH - len(INFO_PACKET_ID)) )
PACKET_ID_LENGTH = len(INFO_PACKET_ID)
VERSION_LENGTH = 4 # https://github.com/irungentoo/toxcore/blob/881b2d900d1998981fb6b9938ec66012d049635f/other/bootstrap_node_packets.c#L44
MAX_MOTD_LENGTH = 256 # https://github.com/irungentoo/toxcore/blob/881b2d900d1998981fb6b9938ec66012d049635f/other/bootstrap_node_packets.c#L26
MAX_INFO_RESPONSE_PACKET_LENGTH = PACKET_ID_LENGTH + VERSION_LENGTH + MAX_MOTD_LENGTH
SOCK_TIMEOUT_SECONDS = 1.0
sock = None
if protocol == "ipv4":
sock = socket(AF_INET, SOCK_DGRAM)
elif protocol == "ipv6":
sock = socket(AF_INET6, SOCK_DGRAM)
else:
print("Invalid first argument")
printHelp()
sys.exit(1)
sock.sendto(INFO_REQUEST_PACKET, (ip, port))
sock.settimeout(SOCK_TIMEOUT_SECONDS)
try:
data, addr = sock.recvfrom(MAX_INFO_RESPONSE_PACKET_LENGTH)
except timeout:
print("The DHT bootstrap node didn't reply in " + str(SOCK_TIMEOUT_SECONDS) + " sec.")
print("The likely reason for that is that the DHT bootstrap node is either offline or has no info set.")
sys.exit(2)
packetId = data[:PACKET_ID_LENGTH]
if packetId != INFO_PACKET_ID:
print("Bad response, first byte should be", INFO_PACKET_ID, "but got", packetId, "(", data, ")")
print("Are you sure that you are pointing the script at a Tox DHT bootstrap node and that the script is up to date?")
sys.exit(3)
version = int.from_bytes(data[PACKET_ID_LENGTH:PACKET_ID_LENGTH + VERSION_LENGTH], byteorder='big')
motd = data[PACKET_ID_LENGTH + VERSION_LENGTH:].decode("utf-8")
print("Version: " + str(version))
print("MOTD: " + motd)
sys.exit(0)

View File

@ -383,7 +383,7 @@ void codec_terminate_session ( CodecState *cs )
free(cs);
}
inline float calculate_sum_sq (int16_t *n, uint16_t k)
static float calculate_sum_sq (int16_t *n, uint16_t k)
{
float result = 0;
uint16_t i = 0;

View File

@ -133,7 +133,7 @@ inline__ void invoke_callback(MSISession* session, int32_t call_index, MSICallba
* @retval -1 Error occurred.
* @retval 0 Success.
*/
int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length )
static int parse_raw_data ( MSIMessage *msg, const uint8_t *data, uint16_t length )
{
#define FAIL_CONSTRAINT(constraint, wanted) if ((constraint -= wanted) < 1) { LOGGER_ERROR("Read over length!"); return -1; }
@ -401,7 +401,7 @@ struct timer_function_args {
* @param timeout Timeout in ms
* @return int
*/
int timer_alloc ( TimerHandler *timers_container, void *(func)(void *), void *arg1, int arg2, unsigned timeout)
static int timer_alloc ( TimerHandler *timers_container, void *(func)(void *), void *arg1, int arg2, unsigned timeout)
{
static int timer_id;
pthread_mutex_lock(&timers_container->mutex);
@ -454,11 +454,11 @@ int timer_alloc ( TimerHandler *timers_container, void *(func)(void *), void *ar
* @brief Remove timer from array
*
* @param timers_container handler
* @param id timer id
* @param idx timer id
* @param lock_mutex (does the mutex need to be locked)
* @return int
*/
int timer_release ( TimerHandler *timers_container, int id , int lock_mutex)
static int timer_release ( TimerHandler *timers_container, int idx , int lock_mutex)
{
if (lock_mutex)
pthread_mutex_lock(&timers_container->mutex);
@ -468,14 +468,14 @@ int timer_release ( TimerHandler *timers_container, int id , int lock_mutex)
int i, res = -1;
for (i = 0; i < timers_container->max_capacity; ++i) {
if (timed_events[i] && timed_events[i]->idx == id) {
if (timed_events[i] && timed_events[i]->idx == idx) {
res = i;
break;
}
}
if (res == -1) {
LOGGER_WARNING("No event with id: %d", id);
LOGGER_WARNING("No event with id: %d", idx);
if (lock_mutex) pthread_mutex_unlock(&timers_container->mutex);
@ -495,7 +495,7 @@ int timer_release ( TimerHandler *timers_container, int id , int lock_mutex)
timers_container->size--;
LOGGER_DEBUG("Popped id: %d, current size: %d ", id, timers_container->size);
LOGGER_DEBUG("Popped id: %d, current size: %d ", idx, timers_container->size);
if (lock_mutex) pthread_mutex_unlock(&timers_container->mutex);
@ -508,7 +508,7 @@ int timer_release ( TimerHandler *timers_container, int id , int lock_mutex)
* @param arg ...
* @return void*
*/
void *timer_poll( void *arg )
static void *timer_poll( void *arg )
{
TimerHandler *handler = arg;
@ -555,7 +555,7 @@ void *timer_poll( void *arg )
* @param resolution ...
* @return TimerHandler*
*/
TimerHandler *timer_init_session (int max_capacity, int resolution)
static TimerHandler *timer_init_session (int max_capacity, int resolution)
{
TimerHandler *handler = calloc(1, sizeof(TimerHandler));
@ -597,7 +597,7 @@ TimerHandler *timer_init_session (int max_capacity, int resolution)
* @param handler The timer handler
* @return void
*/
void timer_terminate_session(TimerHandler *handler)
static void timer_terminate_session(TimerHandler *handler)
{
pthread_mutex_lock(&handler->mutex);
@ -622,7 +622,7 @@ void timer_terminate_session(TimerHandler *handler)
* @param size Size of string.
* @return void
*/
void t_randomstr ( uint8_t *str, uint32_t size )
static void t_randomstr ( uint8_t *str, uint32_t size )
{
if (str == NULL) {
LOGGER_DEBUG("Empty destination!");
@ -687,7 +687,7 @@ static inline__ const uint8_t* stringify_error ( MSICallError error_code )
* @retval -1 Error occurred.
* @retval 0 Success.
*/
int send_message ( MSISession *session, MSICall *call, MSIMessage *msg, uint32_t to )
static int send_message ( MSISession *session, MSICall *call, MSIMessage *msg, uint32_t to )
{
msi_msg_set_callid ( msg, call->id );
@ -723,7 +723,7 @@ inline__ int send_reponse ( MSISession *session, MSICall *call, MSIResponse resp
* @retval 0 it's first
* @retval 1 it's second
*/
int call_id_bigger( const uint8_t *first, const uint8_t *second)
static int call_id_bigger( const uint8_t *first, const uint8_t *second)
{
return (memcmp(first, second, sizeof(MSICallIDType)) < 0);
}
@ -735,9 +735,9 @@ int call_id_bigger( const uint8_t *first, const uint8_t *second)
* @param session Control session.
* @param msg The message.
* @param peer_id The peer.
* @return void
* @return -1, 0
*/
int flush_peer_type ( MSICall *call, MSIMessage *msg, int peer_id )
static int flush_peer_type ( MSICall *call, MSIMessage *msg, int peer_id )
{
if ( msg->calltype.exists ) {
call->type_peer[peer_id] = msg->calltype.value;
@ -748,7 +748,9 @@ int flush_peer_type ( MSICall *call, MSIMessage *msg, int peer_id )
return -1;
}
void handle_remote_connection_change(Messenger *messenger, int friend_num, uint8_t status, void *session_p)
static int terminate_call ( MSISession *session, MSICall *call );
static void handle_remote_connection_change(Messenger *messenger, int friend_num, uint8_t status, void *session_p)
{
MSISession *session = session_p;
@ -778,7 +780,7 @@ void handle_remote_connection_change(Messenger *messenger, int friend_num, uint8
}
}
MSICall *find_call ( MSISession *session, uint8_t *call_id )
static MSICall *find_call ( MSISession *session, uint8_t *call_id )
{
if ( call_id == NULL ) return NULL;
@ -801,7 +803,7 @@ MSICall *find_call ( MSISession *session, uint8_t *call_id )
* @return int
* @retval -1/0 It's usually always success.
*/
int send_error ( MSISession *session, MSICall *call, MSICallError errid, uint32_t to )
static int send_error ( MSISession *session, MSICall *call, MSICallError errid, uint32_t to )
{
if (!call) {
LOGGER_WARNING("Cannot handle error on 'null' call");
@ -828,7 +830,7 @@ int send_error ( MSISession *session, MSICall *call, MSICallError errid, uint32_
* @param peer_id Its id.
* @return void
*/
void add_peer( MSICall *call, int peer_id )
static void add_peer( MSICall *call, int peer_id )
{
uint32_t *peers = !call->peers ? peers = calloc(sizeof(uint32_t), 1) :
realloc( call->peers, sizeof(uint32_t) * call->peer_count);
@ -854,7 +856,7 @@ void add_peer( MSICall *call, int peer_id )
* @param ringing_timeout Ringing timeout.
* @return MSICall* The created call.
*/
MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
static MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
{
if (peers == 0) {
@ -916,7 +918,7 @@ MSICall *init_call ( MSISession *session, int peers, int ringing_timeout )
* @retval -1 Error occurred.
* @retval 0 Success.
*/
int terminate_call ( MSISession *session, MSICall *call )
static int terminate_call ( MSISession *session, MSICall *call )
{
if ( !call ) {
LOGGER_WARNING("Tried to terminate non-existing call!");
@ -956,7 +958,7 @@ int terminate_call ( MSISession *session, MSICall *call )
* @param arg Control session
* @return void*
*/
void *handle_timeout ( void *arg )
static void *handle_timeout ( void *arg )
{
/* TODO: Cancel might not arrive there; set up
* timers on these cancels and terminate call on
@ -988,7 +990,7 @@ void *handle_timeout ( void *arg )
/********** Request handlers **********/
int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *msg )
static int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *msg )
{
LOGGER_DEBUG("Session: %p Handling 'invite' on call: %d", session, call ? call->call_idx : -1);
@ -1082,7 +1084,8 @@ int handle_recv_invite ( MSISession *session, MSICall *call, MSIMessage *msg )
return 1;
}
int handle_recv_start ( MSISession *session, MSICall *call, MSIMessage *msg )
static int handle_recv_start ( MSISession *session, MSICall *call, MSIMessage *msg )
{
if ( !call ) {
LOGGER_WARNING("Session: %p Handling 'start' on no call");
@ -1100,7 +1103,8 @@ int handle_recv_start ( MSISession *session, MSICall *call, MSIMessage *msg )
invoke_callback(session, call->call_idx, MSI_OnStart);
return 1;
}
int handle_recv_reject ( MSISession *session, MSICall *call, MSIMessage *msg )
static int handle_recv_reject ( MSISession *session, MSICall *call, MSIMessage *msg )
{
if ( !call ) {
LOGGER_WARNING("Session: %p Handling 'start' on no call");
@ -1120,7 +1124,8 @@ int handle_recv_reject ( MSISession *session, MSICall *call, MSIMessage *msg )
return 1;
}
int handle_recv_cancel ( MSISession *session, MSICall *call, MSIMessage *msg )
static int handle_recv_cancel ( MSISession *session, MSICall *call, MSIMessage *msg )
{
if ( !call ) {
LOGGER_WARNING("Session: %p Handling 'start' on no call");
@ -1139,7 +1144,8 @@ int handle_recv_cancel ( MSISession *session, MSICall *call, MSIMessage *msg )
return 1;
}
int handle_recv_end ( MSISession *session, MSICall *call, MSIMessage *msg )
static int handle_recv_end ( MSISession *session, MSICall *call, MSIMessage *msg )
{
if ( !call ) {
LOGGER_WARNING("Session: %p Handling 'start' on no call");
@ -1161,7 +1167,7 @@ int handle_recv_end ( MSISession *session, MSICall *call, MSIMessage *msg )
}
/********** Response handlers **********/
int handle_recv_ringing ( MSISession *session, MSICall *call, MSIMessage *msg )
static int handle_recv_ringing ( MSISession *session, MSICall *call, MSIMessage *msg )
{
if ( !call ) {
LOGGER_WARNING("Session: %p Handling 'start' on no call");
@ -1186,7 +1192,7 @@ int handle_recv_ringing ( MSISession *session, MSICall *call, MSIMessage *msg )
invoke_callback(session, call->call_idx, MSI_OnRinging);
return 1;
}
int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage *msg )
static int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage *msg )
{
if ( !call ) {
LOGGER_WARNING("Session: %p Handling 'starting' on non-existing call");
@ -1229,7 +1235,7 @@ int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage *msg )
return 1;
}
int handle_recv_ending ( MSISession *session, MSICall *call, MSIMessage *msg )
static int handle_recv_ending ( MSISession *session, MSICall *call, MSIMessage *msg )
{
if ( !call ) {
LOGGER_WARNING("Session: %p Handling 'start' on no call");
@ -1247,7 +1253,7 @@ int handle_recv_ending ( MSISession *session, MSICall *call, MSIMessage *msg )
return 1;
}
int handle_recv_error ( MSISession *session, MSICall *call, MSIMessage *msg )
static int handle_recv_error ( MSISession *session, MSICall *call, MSIMessage *msg )
{
if ( !call ) {
@ -1306,7 +1312,7 @@ int handle_recv_error ( MSISession *session, MSICall *call, MSIMessage *msg )
*
*
*/
void msi_handle_packet ( Messenger *messenger, int source, const uint8_t *data, uint16_t length, void *object )
static void msi_handle_packet ( Messenger *messenger, int source, const uint8_t *data, uint16_t length, void *object )
{
LOGGER_DEBUG("Got msi message");
/* Unused */
@ -1639,11 +1645,13 @@ int msi_cancel ( MSISession *session, int32_t call_index, uint32_t peer, const c
MSIMessage *msg_cancel = msi_new_message ( TypeRequest, cancel );
#if 0
if ( reason && strlen(reason) < sizeof(MSIReasonStrType) ) {
MSIReasonStrType reason_cast = {0};
memcpy(reason_cast, reason, strlen(reason));
msi_msg_set_reason(msg_cancel, reason_cast);
}
#endif
send_message ( session, session->calls[call_index], msg_cancel, peer );
free ( msg_cancel );
@ -1770,4 +1778,4 @@ int msi_stopcall ( MSISession *session, int32_t call_index )
pthread_mutex_unlock(&session->mutex);
return 0;
}
}

View File

@ -28,6 +28,7 @@
#include "rtp.h"
#include <stdlib.h>
void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg);
#define size_32 4

View File

@ -37,8 +37,9 @@
#include <stdlib.h>
#include <string.h>
/* Assume 60 fps*/
/* Assume 24 fps*/
#define MAX_ENCODE_TIME_US ((1000 / 24) * 1000)
#define MAX_DECODE_TIME_US MAX_ENCODE_TIME_US
#define MAX_VIDEOFRAME_SIZE 0x40000 /* 256KiB */
#define VIDEOFRAME_PIECE_SIZE 0x500 /* 1.25 KiB*/
@ -85,8 +86,8 @@ struct _ToxAv {
const ToxAvCodecSettings av_DefaultSettings = {
500,
800,
600,
1280,
720,
64000,
20,
@ -816,7 +817,7 @@ void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg)
/* piece of current frame */
} else if (i > 0 && i < 128) {
/* recieved a piece of a frame ahead, flush current frame and start reading this new frame */
int rc = vpx_codec_decode(&call->cs->v_decoder, call->frame_buf, call->frame_limit, NULL, 0);
int rc = vpx_codec_decode(&call->cs->v_decoder, call->frame_buf, call->frame_limit, NULL, MAX_DECODE_TIME_US);
call->frame_id = packet[0];
memset(call->frame_buf, 0, call->frame_limit);
call->frame_limit = 0;

View File

@ -183,6 +183,22 @@ void toxav_register_audio_recv_callback (ToxAv *av, void (*callback)(ToxAv *, in
*/
void toxav_register_video_recv_callback (ToxAv *av, void (*callback)(ToxAv *, int32_t, vpx_image_t *));
/**
* @brief Register callback for recieving audio data
*
* @param callback The callback
* @return void
*/
void toxav_register_audio_recv_callback (ToxAv *av, void (*callback)(ToxAv *, int32_t, int16_t *, int));
/**
* @brief Register callback for recieving video data
*
* @param callback The callback
* @return void
*/
void toxav_register_video_recv_callback (ToxAv *av, void (*callback)(ToxAv *, int32_t, vpx_image_t *));
/**
* @brief Call user. Use its friend_id.
*
@ -272,6 +288,7 @@ int toxav_stop_call(ToxAv *av, int32_t call_index);
int toxav_prepare_transmission(ToxAv *av, int32_t call_index, ToxAvCodecSettings *codec_settings, int support_video);
/**
<<<<<<< HEAD
* @brief Call this at the end of the transmission.
*
* @param av Handler.
@ -282,6 +299,8 @@ int toxav_prepare_transmission(ToxAv *av, int32_t call_index, ToxAvCodecSettings
int toxav_kill_transmission(ToxAv *av, int32_t call_index);
/**
=======
>>>>>>> upstream/master
* @brief Encode and send video packet.
*
* @param av Handler.

View File

@ -30,11 +30,72 @@
#define MAX_INTERFACES 16
#ifdef __linux
static int broadcast_count = -1;
static IP_Port broadcast_ip_port[MAX_INTERFACES];
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
#include <iphlpapi.h>
static void fetch_broadcast_info(uint16_t port)
{
broadcast_count = 0;
IP_ADAPTER_INFO *pAdapterInfo = malloc(sizeof(pAdapterInfo));
unsigned long ulOutBufLen = sizeof(pAdapterInfo);
if (pAdapterInfo == NULL) {
printf("Error allocating memory for pAdapterInfo\n");
return;
}
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
free(pAdapterInfo);
pAdapterInfo = malloc(ulOutBufLen);
if (pAdapterInfo == NULL) {
printf("Error allocating memory needed to call GetAdaptersinfo\n");
return;
}
}
int ret;
if ((ret = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
IP_ADAPTER_INFO *pAdapter = pAdapterInfo;
while (pAdapter) {
IP gateway = {0}, subnet_mask = {0};
if (addr_parse_ip(pAdapter->IpAddressList.IpMask.String, &subnet_mask)
&& addr_parse_ip(pAdapter->GatewayList.IpAddress.String, &gateway)) {
if (gateway.family == AF_INET && subnet_mask.family == AF_INET) {
IP_Port *ip_port = &broadcast_ip_port[broadcast_count];
ip_port->ip.family = AF_INET;
uint32_t gateway_ip = ntohl(gateway.ip4.uint32), subnet_ip = ntohl(subnet_mask.ip4.uint32);
uint32_t broadcast_ip = gateway_ip + ~subnet_ip - 1;
ip_port->ip.ip4.uint32 = htonl(broadcast_ip);
ip_port->port = port;
broadcast_count++;
printf("broadcast ip: %s\n", ip_ntoa(&ip_port->ip));
if (broadcast_count >= MAX_INTERFACES) {
return;
}
}
}
pAdapter = pAdapter->Next;
}
} else {
printf("Fetching adapter info failed %i\n", ret);
}
}
#elif defined(__linux__)
static void fetch_broadcast_info(uint16_t port)
{
/* Not sure how many platforms this will run on,
@ -93,6 +154,14 @@ static void fetch_broadcast_info(uint16_t port)
close(sock);
}
#else //TODO: Other platforms?
static void fetch_broadcast_info(uint16_t port)
{
broadcast_count = 0;
}
#endif
/* Send packet to all IPv4 broadcast addresses
*
* return 1 if sent to at least one broadcast target.
@ -115,7 +184,6 @@ static uint32_t send_broadcasts(Networking_Core *net, uint16_t port, const uint8
return 1;
}
#endif /* __linux */
/* Return the broadcast ip. */
static IP broadcast_ip(sa_family_t family_socket, sa_family_t family_broadcast)
@ -228,9 +296,8 @@ int send_LANdiscovery(uint16_t port, DHT *dht)
data[0] = NET_PACKET_LAN_DISCOVERY;
id_copy(data + 1, dht->self_public_key);
#ifdef __linux
send_broadcasts(dht->net, port, data, 1 + crypto_box_PUBLICKEYBYTES);
#endif
int res = -1;
IP_Port ip_port;
ip_port.port = port;

View File

@ -1206,8 +1206,10 @@ int join_groupchat(Messenger *m, int32_t friendnumber, const uint8_t *friend_gro
IP_Port friend_ip = get_friend_ipport(m, friendnumber);
if (friend_ip.ip.family == 0)
if (friend_ip.ip.family == 0) {
del_groupchat(m, groupnum);
return -1;
}
id_copy(data, friend_group_public_key);
id_copy(data + crypto_box_PUBLICKEYBYTES, m->chats[groupnum]->self_public_key);
@ -1218,6 +1220,7 @@ int join_groupchat(Messenger *m, int32_t friendnumber, const uint8_t *friend_gro
return groupnum;
}
del_groupchat(m, groupnum);
return -1;
}
@ -2598,6 +2601,10 @@ static int friends_list_load(Messenger *m, const uint8_t *data, uint32_t length)
if (temp.status >= 3) {
int fnum = m_addfriend_norequest(m, temp.client_id);
if (fnum < 0)
continue;
setfriendname(m, fnum, temp.name, ntohs(temp.name_length));
set_friend_statusmessage(m, fnum, temp.statusmessage, ntohs(temp.statusmessage_length));
set_friend_userstatus(m, fnum, temp.userstatus);

View File

@ -109,7 +109,7 @@ static int handle_handshake(TCP_Client_Connection *TCP_conn, const uint8_t *data
/* return 0 if pending data was sent completely
* return -1 if it wasn't
*/
static int send_pending_data(TCP_Client_Connection *con)
static int send_pending_data_nonpriority(TCP_Client_Connection *con)
{
if (con->last_packet_length == 0) {
return 0;
@ -127,24 +127,95 @@ static int send_pending_data(TCP_Client_Connection *con)
return 0;
}
if (len > left)
return -1;
con->last_packet_sent += len;
return -1;
}
/* return 0 if pending data was sent completely
* return -1 if it wasn't
*/
static int send_pending_data(TCP_Client_Connection *con)
{
/* finish sending current non-priority packet */
if (send_pending_data_nonpriority(con) == -1) {
return -1;
}
TCP_Priority_List *p = con->priority_queue_start;
while (p) {
uint16_t left = p->size - p->sent;
int len = send(con->sock, p->data + p->sent, left, MSG_NOSIGNAL);
if (len != left) {
if (len > 0) {
p->sent += len;
}
break;
}
TCP_Priority_List *pp = p;
p = p->next;
free(pp);
}
con->priority_queue_start = p;
if (!p) {
con->priority_queue_end = NULL;
return 0;
}
return -1;
}
/* return 0 on failure (only if malloc fails)
* return 1 on success
*/
static _Bool add_priority(TCP_Client_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent)
{
TCP_Priority_List *p = con->priority_queue_end, *new;
new = malloc(sizeof(TCP_Priority_List) + size);
if (!new) {
return 0;
}
new->next = NULL;
new->size = size;
new->sent = sent;
memcpy(new->data, packet, size);
if (p) {
p->next = new;
} else {
con->priority_queue_start = new;
}
con->priority_queue_end = new;
return 1;
}
/* return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const uint8_t *data, uint16_t length)
static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const uint8_t *data, uint16_t length,
_Bool priority)
{
if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
return -1;
if (send_pending_data(con) == -1)
return 0;
_Bool sendpriority = 1;
if (send_pending_data(con) == -1) {
if (priority) {
sendpriority = 0;
} else {
return 0;
}
}
uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];
@ -155,17 +226,33 @@ static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const
if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t)))
return -1;
increment_nonce(con->sent_nonce);
if (priority) {
len = sendpriority ? send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL) : 0;
if (len <= 0) {
len = 0;
}
increment_nonce(con->sent_nonce);
if (len == sizeof(packet)) {
return 1;
}
return add_priority(con, packet, sizeof(packet), len);
}
len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL);
if ((unsigned int)len == sizeof(packet))
return 1;
if (len <= 0)
return 0;
memcpy(con->last_packet, packet, length);
increment_nonce(con->sent_nonce);
if ((unsigned int)len == sizeof(packet))
return 1;
memcpy(con->last_packet, packet, sizeof(packet));
con->last_packet_length = sizeof(packet);
con->last_packet_sent = len;
return 1;
@ -180,7 +267,7 @@ int send_routing_request(TCP_Client_Connection *con, uint8_t *public_key)
uint8_t packet[1 + crypto_box_PUBLICKEYBYTES];
packet[0] = TCP_PACKET_ROUTING_REQUEST;
memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1);
}
void routing_response_handler(TCP_Client_Connection *con, int (*response_callback)(void *object, uint8_t connection_id,
@ -197,6 +284,9 @@ void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(v
con->status_callback_object = object;
}
static int send_ping_response(TCP_Client_Connection *con);
static int send_ping_request(TCP_Client_Connection *con);
/* return 1 on success.
* return 0 if could not send packet.
* return -1 on failure.
@ -209,10 +299,13 @@ int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, u
if (con->connections[con_id].status != 2)
return -1;
if (send_ping_response(con) == 0 || send_ping_request(con) == 0)
return 0;
uint8_t packet[1 + length];
packet[0] = con_id + NUM_RESERVED_PORTS;
memcpy(packet + 1, data, length);
return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0);
}
/* return 1 on success.
@ -228,7 +321,7 @@ int send_oob_packet(TCP_Client_Connection *con, const uint8_t *public_key, const
packet[0] = TCP_PACKET_OOB_SEND;
memcpy(packet + 1, public_key, crypto_box_PUBLICKEYBYTES);
memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, data, length);
return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0);
}
@ -274,31 +367,49 @@ static int send_disconnect_notification(TCP_Client_Connection *con, uint8_t id)
uint8_t packet[1 + 1];
packet[0] = TCP_PACKET_DISCONNECT_NOTIFICATION;
packet[1] = id;
return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1);
}
/* return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
static int send_ping_request(TCP_Client_Connection *con, uint64_t ping_id)
static int send_ping_request(TCP_Client_Connection *con)
{
if (!con->ping_request_id)
return 1;
uint8_t packet[1 + sizeof(uint64_t)];
packet[0] = TCP_PACKET_PING;
memcpy(packet + 1, &ping_id, sizeof(uint64_t));
return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t));
int ret;
if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1)) == 1) {
con->ping_request_id = 0;
}
return ret;
}
/* return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
static int send_ping_response(TCP_Client_Connection *con, uint64_t ping_id)
static int send_ping_response(TCP_Client_Connection *con)
{
if (!con->ping_response_id)
return 1;
uint8_t packet[1 + sizeof(uint64_t)];
packet[0] = TCP_PACKET_PONG;
memcpy(packet + 1, &ping_id, sizeof(uint64_t));
return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t));
int ret;
if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1)) == 1) {
con->ping_response_id = 0;
}
return ret;
}
/* return 1 on success.
@ -324,7 +435,7 @@ int send_onion_request(TCP_Client_Connection *con, const uint8_t *data, uint16_t
uint8_t packet[1 + length];
packet[0] = TCP_PACKET_ONION_REQUEST;
memcpy(packet + 1, data, length);
return write_packet_TCP_secure_connection(con, packet, sizeof(packet));
return write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0);
}
void onion_response_handler(TCP_Client_Connection *con, int (*onion_callback)(void *object, const uint8_t *data,
@ -427,7 +538,7 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, u
uint8_t con_id = data[1] - NUM_RESERVED_PORTS;
if (conn->connections[con_id].status != 1)
return -1;
return 0;
conn->connections[con_id].status = 2;
@ -451,7 +562,7 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, u
return 0;
if (conn->connections[con_id].status != 2)
return -1;
return 0;
conn->connections[con_id].status = 1;
@ -468,7 +579,8 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, u
uint64_t ping_id;
memcpy(&ping_id, data + 1, sizeof(uint64_t));
send_ping_response(conn, ping_id);
conn->ping_response_id = ping_id;
send_ping_response(conn);
return 0;
}
@ -523,6 +635,9 @@ static int handle_TCP_packet(TCP_Client_Connection *conn, const uint8_t *data, u
static int do_confirmed_TCP(TCP_Client_Connection *conn)
{
send_pending_data(conn);
send_ping_response(conn);
send_ping_request(conn);
uint8_t packet[MAX_PACKET_SIZE];
int len;
@ -532,16 +647,9 @@ static int do_confirmed_TCP(TCP_Client_Connection *conn)
if (!ping_id)
++ping_id;
int ret = send_ping_request(conn, ping_id);
if (ret == 1) {
conn->last_pinged = unix_time();
conn->ping_id = ping_id;
} else {
if (is_timeout(conn->last_pinged, TCP_PING_FREQUENCY + TCP_PING_TIMEOUT)) {
conn->status = TCP_CLIENT_DISCONNECTED;
}
}
conn->ping_request_id = conn->ping_id = ping_id;
send_ping_request(conn);
conn->last_pinged = unix_time();
}
if (conn->ping_id && is_timeout(conn->last_pinged, TCP_PING_TIMEOUT)) {

View File

@ -52,11 +52,16 @@ typedef struct {
uint16_t last_packet_length;
uint16_t last_packet_sent;
TCP_Priority_List *priority_queue_start, *priority_queue_end;
uint64_t kill_at;
uint64_t last_pinged;
uint64_t ping_id;
uint64_t ping_response_id;
uint64_t ping_request_id;
void *net_crypto_pointer;
uint32_t net_crypto_location;
struct {

View File

@ -288,7 +288,7 @@ int read_packet_TCP_secure_connection(sock_t sock, uint16_t *next_packet_length,
/* return 0 if pending data was sent completely
* return -1 if it wasn't
*/
static int send_pending_data(TCP_Secure_Connection *con)
static int send_pending_data_nonpriority(TCP_Secure_Connection *con)
{
if (con->last_packet_length == 0) {
return 0;
@ -306,25 +306,96 @@ static int send_pending_data(TCP_Secure_Connection *con)
return 0;
}
if (len > left)
return -1;
con->last_packet_sent += len;
return -1;
}
/* return 0 if pending data was sent completely
* return -1 if it wasn't
*/
static int send_pending_data(TCP_Secure_Connection *con)
{
/* finish sending current non-priority packet */
if (send_pending_data_nonpriority(con) == -1) {
return -1;
}
TCP_Priority_List *p = con->priority_queue_start;
while (p) {
uint16_t left = p->size - p->sent;
int len = send(con->sock, p->data + p->sent, left, MSG_NOSIGNAL);
if (len != left) {
if (len > 0) {
p->sent += len;
}
break;
}
TCP_Priority_List *pp = p;
p = p->next;
free(pp);
}
con->priority_queue_start = p;
if (!p) {
con->priority_queue_end = NULL;
return 0;
}
return -1;
}
/* return 0 on failure (only if malloc fails)
* return 1 on success
*/
static _Bool add_priority(TCP_Secure_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent)
{
TCP_Priority_List *p = con->priority_queue_end, *new;
new = malloc(sizeof(TCP_Priority_List) + size);
if (!new) {
return 0;
}
new->next = NULL;
new->size = size;
new->sent = sent;
memcpy(new->data, packet, size);
if (p) {
p->next = new;
} else {
con->priority_queue_start = new;
}
con->priority_queue_end = new;
return 1;
}
/* return 1 on success.
* return 0 if could not send packet.
* return -1 on failure (connection must be killed).
*/
static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length)
static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const uint8_t *data, uint16_t length,
_Bool priority)
{
if (length + crypto_box_MACBYTES > MAX_PACKET_SIZE)
return -1;
if (send_pending_data(con) == -1)
return 0;
_Bool sendpriority = 1;
if (send_pending_data(con) == -1) {
if (priority) {
sendpriority = 0;
} else {
return 0;
}
}
uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES];
@ -335,17 +406,33 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const
if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t)))
return -1;
increment_nonce(con->sent_nonce);
if (priority) {
len = sendpriority ? send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL) : 0;
if (len <= 0) {
len = 0;
}
increment_nonce(con->sent_nonce);
if (len == sizeof(packet)) {
return 1;
}
return add_priority(con, packet, sizeof(packet), len);
}
len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL);
if ((unsigned int)len == sizeof(packet))
return 1;
if (len <= 0)
return 0;
memcpy(con->last_packet, packet, length);
increment_nonce(con->sent_nonce);
if ((unsigned int)len == sizeof(packet))
return 1;
memcpy(con->last_packet, packet, sizeof(packet));
con->last_packet_length = sizeof(packet);
con->last_packet_sent = len;
return 1;
@ -459,7 +546,7 @@ static int send_routing_response(TCP_Secure_Connection *con, uint8_t rpid, const
data[1] = rpid;
memcpy(data + 2, public_key, crypto_box_PUBLICKEYBYTES);
return write_packet_TCP_secure_connection(con, data, sizeof(data));
return write_packet_TCP_secure_connection(con, data, sizeof(data), 1);
}
/* return 1 on success.
@ -469,7 +556,7 @@ static int send_routing_response(TCP_Secure_Connection *con, uint8_t rpid, const
static int send_connect_notification(TCP_Secure_Connection *con, uint8_t id)
{
uint8_t data[2] = {TCP_PACKET_CONNECTION_NOTIFICATION, id + NUM_RESERVED_PORTS};
return write_packet_TCP_secure_connection(con, data, sizeof(data));
return write_packet_TCP_secure_connection(con, data, sizeof(data), 1);
}
/* return 1 on success.
@ -479,7 +566,7 @@ static int send_connect_notification(TCP_Secure_Connection *con, uint8_t id)
static int send_disconnect_notification(TCP_Secure_Connection *con, uint8_t id)
{
uint8_t data[2] = {TCP_PACKET_DISCONNECT_NOTIFICATION, id + NUM_RESERVED_PORTS};
return write_packet_TCP_secure_connection(con, data, sizeof(data));
return write_packet_TCP_secure_connection(con, data, sizeof(data), 1);
}
/* return 0 on success.
@ -579,7 +666,7 @@ static int handle_TCP_oob_send(TCP_Server *TCP_server, uint32_t con_id, const ui
memcpy(resp_packet + 1, con->public_key, crypto_box_PUBLICKEYBYTES);
memcpy(resp_packet + 1 + crypto_box_PUBLICKEYBYTES, data, length);
write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[other_index], resp_packet,
sizeof(resp_packet));
sizeof(resp_packet), 0);
}
return 0;
@ -637,7 +724,7 @@ static int handle_onion_recv_1(void *object, IP_Port dest, const uint8_t *data,
memcpy(packet + 1, data, length);
packet[0] = TCP_PACKET_ONION_RESPONSE;
if (write_packet_TCP_secure_connection(con, packet, sizeof(packet)) != 1)
if (write_packet_TCP_secure_connection(con, packet, sizeof(packet), 0) != 1)
return 1;
return 0;
@ -682,7 +769,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint
uint8_t response[1 + sizeof(uint64_t)];
response[0] = TCP_PACKET_PONG;
memcpy(response + 1, data + 1, sizeof(uint64_t));
write_packet_TCP_secure_connection(con, response, sizeof(response));
write_packet_TCP_secure_connection(con, response, sizeof(response), 1);
return 0;
}
@ -752,7 +839,7 @@ static int handle_TCP_packet(TCP_Server *TCP_server, uint32_t con_id, const uint
uint8_t new_data[length];
memcpy(new_data, data, length);
new_data[0] = other_c_id;
int ret = write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[index], new_data, length);
int ret = write_packet_TCP_secure_connection(&TCP_server->accepted_connection_array[index], new_data, length, 0);
if (ret == -1)
return -1;
@ -1058,7 +1145,7 @@ static void do_TCP_confirmed(TCP_Server *TCP_server)
++ping_id;
memcpy(ping + 1, &ping_id, sizeof(uint64_t));
int ret = write_packet_TCP_secure_connection(conn, ping, sizeof(ping));
int ret = write_packet_TCP_secure_connection(conn, ping, sizeof(ping), 1);
if (ret == 1) {
conn->last_pinged = unix_time();

View File

@ -80,6 +80,14 @@ enum {
TCP_STATUS_CONFIRMED,
};
typedef struct TCP_Priority_List TCP_Priority_List;
struct TCP_Priority_List {
TCP_Priority_List *next;
uint16_t size, sent;
uint8_t data[0];
};
typedef struct TCP_Secure_Connection {
uint8_t status;
sock_t sock;
@ -98,6 +106,8 @@ typedef struct TCP_Secure_Connection {
uint16_t last_packet_length;
uint16_t last_packet_sent;
TCP_Priority_List *priority_queue_start, *priority_queue_end;
uint64_t identifier;
uint64_t last_pinged;

View File

@ -471,16 +471,6 @@ static int handle_sendnodes(Group_Chat *chat, IP_Port source, int peernum, const
int ok = add_closepeer(chat, chat->group[peernum].client_id, source);
if (chat->assoc) {
ippts_send.ip_port = chat->group[peernum].ping_via;
ippts_send.timestamp = chat->group[peernum].last_pinged;
IP_Port ipp_recv;
ipp_recv = source;
Assoc_add_entry(chat->assoc, contents.nodes[i].client_id, &ippts_send, &ipp_recv, ok == 0 ? 1 : 0);
}
return 0;
}
@ -830,6 +820,7 @@ void do_groupchat(Group_Chat *chat)
void kill_groupchat(Group_Chat *chat)
{
send_data(chat, 0, 0, GROUP_CHAT_QUIT);
kill_Assoc(chat->assoc);
free(chat->group);
free(chat);
}

View File

@ -37,21 +37,6 @@ static uint8_t crypt_connection_id_not_valid(const Net_Crypto *c, int crypt_conn
return (uint32_t)crypt_connection_id >= c->crypto_connections_length;
}
/* return 0 if connection is dead.
* return 1 if connection is alive.
*/
static int is_alive(uint8_t status)
{
if (status == CRYPTO_CONN_COOKIE_REQUESTING ||
status == CRYPTO_CONN_HANDSHAKE_SENT ||
status == CRYPTO_CONN_NOT_CONFIRMED ||
status == CRYPTO_CONN_ESTABLISHED) {
return 1;
}
return 0;
}
/* cookie timeout in seconds */
#define COOKIE_TIMEOUT 10
#define COOKIE_DATA_LENGTH (crypto_box_PUBLICKEYBYTES * 2)
@ -426,19 +411,22 @@ static int send_packet_to(const Net_Crypto *c, int crypt_connection_id, const ui
}
//TODO: spread packets over many relays, detect and kill bad relays.
//TODO: detect and kill bad relays.
uint32_t i;
unsigned int r = rand();
for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
if (conn->status_tcp[i] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */
if (send_data(c->tcp_connections[i], conn->con_number_tcp[i], data, length) == 1)
if (conn->status_tcp[(i + r) % MAX_TCP_CONNECTIONS] == STATUS_TCP_ONLINE) {/* friend is connected to this relay. */
if (send_data(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], conn->con_number_tcp[(i + r) % MAX_TCP_CONNECTIONS],
data, length) == 1)
return 0;
}
}
for (i = 0; i < MAX_TCP_CONNECTIONS; ++i) {
if (conn->status_tcp[i] == STATUS_TCP_INVISIBLE) {
if (send_oob_packet(c->tcp_connections[i], conn->dht_public_key, data, length) == 1)
if (conn->status_tcp[(i + r) % MAX_TCP_CONNECTIONS] == STATUS_TCP_INVISIBLE) {
if (send_oob_packet(c->tcp_connections[(i + r) % MAX_TCP_CONNECTIONS], conn->dht_public_key, data, length) == 1)
return 0;
}
}
@ -1106,6 +1094,14 @@ static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_i
return -1;
}
if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
clear_temp_packet(c, crypt_connection_id);
conn->status = CRYPTO_CONN_ESTABLISHED;
if (conn->connection_status_callback)
conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1);
}
if (real_data[0] == PACKET_ID_REQUEST) {
int requested = handle_request_packet(&conn->send_array, real_data, real_length);
@ -1148,14 +1144,6 @@ static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_i
return -1;
}
if (conn->status == CRYPTO_CONN_NOT_CONFIRMED) {
if (conn->connection_status_callback)
conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1);
clear_temp_packet(c, crypt_connection_id);
conn->status = CRYPTO_CONN_ESTABLISHED;
}
return 0;
}
@ -1485,6 +1473,7 @@ int accept_crypto_connection(Net_Crypto *c, New_Connection *n_c)
/* Status needs to be CRYPTO_CONN_NOT_CONFIRMED for this to work. */
set_connection_dht_public_key(c, crypt_connection_id, n_c->dht_public_key, current_time_monotonic());
conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
crypto_connection_add_source(c, crypt_connection_id, n_c->source);
return crypt_connection_id;
}
@ -1517,6 +1506,7 @@ int new_crypto_connection(Net_Crypto *c, const uint8_t *real_public_key)
crypto_box_keypair(conn->sessionpublic_key, conn->sessionsecret_key);
conn->status = CRYPTO_CONN_COOKIE_REQUESTING;
conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
conn->packets_left = CRYPTO_MIN_QUEUE_LENGTH;
return crypt_connection_id;
}
@ -2250,6 +2240,15 @@ static void send_crypto_packets(Net_Crypto *c)
notes: needs improvement but seems to work fine for packet loss <1%
*/
/* additional step: adjust the send rate based on the size change of the send queue */
uint32_t queue_size = num_packets_array(&conn->send_array);
if (queue_size > conn->packet_send_rate && queue_size > conn->last_queue_size) {
conn->rate_increase = 0;
conn->packets_resent = conn->packets_sent;
}
//hack to prevent 1 packet lost from affecting calculations at low send rates
if (conn->packets_resent == 1) {
conn->packets_resent = 0;
@ -2300,18 +2299,27 @@ static void send_crypto_packets(Net_Crypto *c)
double linear_increase = realrate * 0.0025 + 1.0;
//final send rate: average of "real" and previous send rates + increases
conn->packet_send_rate = (realrate + conn->packet_send_rate) / 2.0 + conn->rate_increase + linear_increase;
double newrate = (realrate + conn->packet_send_rate) / 2.0 + conn->rate_increase + linear_increase;
conn->last_send_rate = conn->packet_send_rate;
conn->packet_send_rate = newrate;
conn->dropped = dropped;
conn->drop_ignore = drop_ignore_new;
conn->packets_resent = 0;
conn->last_queue_size = queue_size;
if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE || !conn->sending) {
if (!conn->sending || !conn->packets_sent) {
conn->rate_increase = 0;
conn->packet_send_rate /= 2;
}
if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE) {
conn->packet_send_rate = CRYPTO_PACKET_MIN_RATE;
}
conn->packets_sent = 0;
if (conn->sending != 0 && num_packets_array(&conn->send_array) < CRYPTO_MIN_QUEUE_LENGTH / 2) {
--conn->sending;
}
@ -2342,6 +2350,7 @@ static void send_crypto_packets(Net_Crypto *c)
conn->packets_resent += ret;
conn->packets_left -= ret;
conn->packets_sent += ret;
}
if (conn->packet_send_rate > CRYPTO_PACKET_MIN_RATE * 1.5) {
@ -2421,6 +2430,7 @@ int64_t write_cryptpacket(const Net_Crypto *c, int crypt_connection_id, const ui
return -1;
--conn->packets_left;
conn->packets_sent++;
conn->sending = CONN_SENDING_VALUE;
return ret;
}

View File

@ -143,9 +143,9 @@ typedef struct {
uint32_t packets_left;
uint64_t last_packets_left_set;
double dropped, drop_ignore, rate_increase;
double dropped, drop_ignore, rate_increase, last_send_rate;
uint64_t drop_ignore_start, rate_increase_stop_start;
uint32_t packets_resent;
uint32_t packets_resent, last_queue_size, packets_sent, last_packets_sent;
uint8_t sending; /* indicates if data is being sent or not. */

View File

@ -671,7 +671,7 @@ int ip_equal(const IP *a, const IP *b)
}
return 0;
};
}
/* ipport_equal
* compares two IPAny_Port structures
@ -688,7 +688,7 @@ int ipport_equal(const IP_Port *a, const IP_Port *b)
return 0;
return ip_equal(&a->ip, &b->ip);
};
}
/* nulls out ip */
void ip_reset(IP *ip)
@ -697,7 +697,7 @@ void ip_reset(IP *ip)
return;
memset(ip, 0, sizeof(IP));
};
}
/* nulls out ip, sets family according to flag */
void ip_init(IP *ip, uint8_t ipv6enabled)
@ -707,7 +707,7 @@ void ip_init(IP *ip, uint8_t ipv6enabled)
memset(ip, 0, sizeof(IP));
ip->family = ipv6enabled ? AF_INET6 : AF_INET;
};
}
/* checks if ip is valid */
int ip_isset(const IP *ip)
@ -716,7 +716,7 @@ int ip_isset(const IP *ip)
return 0;
return (ip->family != 0);
};
}
/* checks if ip is valid */
int ipport_isset(const IP_Port *ipport)
@ -728,7 +728,7 @@ int ipport_isset(const IP_Port *ipport)
return 0;
return ip_isset(&ipport->ip);
};
}
/* copies an ip structure (careful about direction!) */
void ip_copy(IP *target, const IP *source)
@ -737,7 +737,7 @@ void ip_copy(IP *target, const IP *source)
return;
memcpy(target, source, sizeof(IP));
};
}
/* copies an ip_port structure (careful about direction!) */
void ipport_copy(IP_Port *target, const IP_Port *source)
@ -805,7 +805,7 @@ const char *ip_ntoa(const IP *ip)
/* brute force protection against lacking termination */
addresstext[sizeof(addresstext) - 1] = 0;
return addresstext;
};
}
/*
* addr_parse_ip
@ -820,7 +820,6 @@ const char *ip_ntoa(const IP *ip)
*
* returns 1 on success, 0 on failure
*/
int addr_parse_ip(const char *address, IP *to)
{
if (!address || !to)
@ -832,7 +831,7 @@ int addr_parse_ip(const char *address, IP *to)
to->family = AF_INET;
to->ip4.in_addr = addr4;
return 1;
};
}
struct in6_addr addr6;
@ -840,10 +839,10 @@ int addr_parse_ip(const char *address, IP *to)
to->family = AF_INET6;
to->ip6.in6_addr = addr6;
return 1;
};
}
return 0;
};
}
/*
* addr_resolve():
@ -862,7 +861,6 @@ int addr_parse_ip(const char *address, IP *to)
* returns in *extra an IPv4 address, if family was AF_UNSPEC and *to is AF_INET6
* returns 0 on failure
*/
int addr_resolve(const char *address, IP *to, IP *extra)
{
if (!address || !to)
@ -970,4 +968,4 @@ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra)
return 0;
return 1;
};
}

View File

@ -191,6 +191,21 @@ IP_Port;
*/
const char *ip_ntoa(const IP *ip);
/*
* addr_parse_ip
* directly parses the input into an IP structure
* tries IPv4 first, then IPv6
*
* input
* address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6)
*
* output
* IP: family and the value is set on success
*
* returns 1 on success, 0 on failure
*/
int addr_parse_ip(const char *address, IP *to);
/* ip_equal
* compares two IPAny structures
* unset means unequal

View File

@ -831,7 +831,7 @@ int onion_delfriend(Onion_Client *onion_c, int friend_num)
uint32_t i;
for (i = onion_c->num_friends; i != 0; --i) {
if (onion_c->friends_list[i].status != 0)
if (onion_c->friends_list[i - 1].status != 0)
break;
}

View File

@ -135,7 +135,7 @@ int ping_array_init(Ping_Array *empty_array, uint32_t size, uint32_t timeout)
if (size == 0 || timeout == 0 || empty_array == NULL)
return -1;
empty_array->entries = calloc(size * sizeof(Ping_Array_Entry), 1);
empty_array->entries = calloc(size, sizeof(Ping_Array_Entry));
if (empty_array->entries == NULL)
return -1;

View File

@ -90,7 +90,7 @@ void tox_get_address(const Tox *tox, uint8_t *address);
* data is the data and length is the length.
*
* return the friend number if success.
* return TOX_FA_TOOLONG if message length is too long.
* return TOX_FAERR_TOOLONG if message length is too long.
* return TOX_FAERR_NOMESSAGE if no message (message length must be >= 1 byte).
* return TOX_FAERR_OWNKEY if user's own key.
* return TOX_FAERR_ALREADYSENT if friend request already sent or already a friend.
@ -294,13 +294,13 @@ void tox_callback_friend_request(Tox *tox, void (*function)(Tox *tox, const uint
void *), void *userdata);
/* Set the function that will be executed when a message from a friend is received.
* Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * message, uint32_t length, void *userdata)
* Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * message, uint16_t length, void *userdata)
*/
void tox_callback_friend_message(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *),
void *userdata);
/* Set the function that will be executed when an action from a friend is received.
* Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * action, uint32_t length, void *userdata)
* Function format is: function(Tox *tox, int32_t friendnumber, uint8_t * action, uint16_t length, void *userdata)
*/
void tox_callback_friend_action(Tox *tox, void (*function)(Tox *tox, int32_t, const uint8_t *, uint16_t, void *),
void *userdata);
@ -495,20 +495,20 @@ uint32_t tox_get_chatlist(const Tox *tox, int *out_list, uint32_t list_size);
* tox_file_data_remaining(...) can be used to know how many bytes are left to send/receive.
*
* If the connection breaks during file sending (The other person goes offline without pausing the sending and then comes back)
* the receiver must send a control packet with receive_send == 0 message_id = TOX_FILECONTROL_RESUME_BROKEN and the data being
* the receiver must send a control packet with send_receive == 1 message_id = TOX_FILECONTROL_RESUME_BROKEN and the data being
* a uint64_t (in host byte order) containing the number of bytes received.
*
* If the sender receives this packet, he must send a control packet with receive_send == 1 and control_type == TOX_FILECONTROL_ACCEPT
* If the sender receives this packet, he must send a control packet with send_receive == 0 and control_type == TOX_FILECONTROL_ACCEPT
* then he must start sending file data from the position (data , uint64_t in host byte order) received in the TOX_FILECONTROL_RESUME_BROKEN packet.
*
* To pause a file transfer send a control packet with control_type == TOX_FILECONTROL_PAUSE.
* To unpause a file transfer send a control packet with control_type == TOX_FILECONTROL_ACCEPT.
*
* If you receive a control packet with receive_send == 1 and control_type == TOX_FILECONTROL_PAUSE, you must stop sending filenumber until the other
* person sends a control packet with receive_send == 1 and control_type == TOX_FILECONTROL_ACCEPT with the filenumber being a paused filenumber.
* person sends a control packet with send_receive == 0 and control_type == TOX_FILECONTROL_ACCEPT with the filenumber being a paused filenumber.
*
* If you receive a control packet with receive_send == 0 and control_type == TOX_FILECONTROL_PAUSE, it means the sender of filenumber has paused the
* transfer and will resume it later with a control packet with receive_send == 0 and control_type == TOX_FILECONTROL_ACCEPT for that file number.
* transfer and will resume it later with a control packet with send_receive == 1 and control_type == TOX_FILECONTROL_ACCEPT for that file number.
*
* More to come...
*/

View File

@ -25,4 +25,5 @@ libtoxdns_la_LDFLAGS = $(TOXCORE_LT_LDFLAGS) \
libtoxdns_la_LIBADD = $(LIBSODIUM_LIBS) \
$(NACL_OBJECTS) \
$(NAC_LIBS) \
$(PTHREAD_LIBS)
$(PTHREAD_LIBS) \
libtoxcore.la