mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Fixed conflicts
This commit is contained in:
commit
79115259a8
26
INSTALL.md
26
INSTALL.md
|
@ -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:
|
||||
|
|
|
@ -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 />
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
21
configure.ac
21
configure.ac
|
@ -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)
|
||||
],
|
||||
[
|
||||
|
|
|
@ -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
104
m4/ax_have_epoll.m4
Normal 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
|
98
other/fun/bootstrap_node_info.py
Normal file
98
other/fun/bootstrap_node_info.py
Normal 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)
|
|
@ -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;
|
||||
|
|
72
toxav/msi.c
72
toxav/msi.c
|
@ -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 );
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "rtp.h"
|
||||
#include <stdlib.h>
|
||||
void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg);
|
||||
|
||||
#define size_32 4
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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...
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user