From ab6643cef7041edc01517cbb86da3e82dfda1ca1 Mon Sep 17 00:00:00 2001 From: mouseym Date: Thu, 3 Jul 2014 23:02:48 +0100 Subject: [PATCH 01/50] Update OSX install instructions in INSTALL.md Removed unnecessary steps, added support for A/V libs in core and missing dependencies. --- INSTALL.md | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 1aed5375..71a66123 100644 --- a/INSTALL.md +++ b/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. 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: +Change to your local Tox repository and: -Then generate makefile, build and install tox: ```bash cd ProjectTox-Core autoreconf -i @@ -170,12 +177,11 @@ 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. ###Windows: From d7500bcc9b85f2c1fe9a2d5bc71aebd0dd9b31ed Mon Sep 17 00:00:00 2001 From: mouseym Date: Fri, 4 Jul 2014 09:10:54 +0100 Subject: [PATCH 02/50] Some extra fixes. --- INSTALL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 71a66123..6cdec95b 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -157,7 +157,7 @@ Grab the following packages: 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 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: @@ -167,7 +167,7 @@ make sudo make install ``` -Change to your local Tox repository and: +Compiling and installing Tox Core ```bash cd ProjectTox-Core From bdb00322e3ecb9eb213ce01688089cdad39304f0 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 5 Jul 2014 12:46:58 -0400 Subject: [PATCH 03/50] Fixed bug when loading friends list already containing an added friend. --- toxcore/Messenger.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 4344fdcb..2adbd870 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -2598,6 +2598,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); From 65b4c026f4a2aa965f89f28958fe75bceb16475c Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 5 Jul 2014 14:36:19 -0400 Subject: [PATCH 04/50] The width and height set during the video encoder initialization is now described as the maximum width and height of images. This is to work around what appears to be a bug in libvpx where the resolution of the stream can be decreased but increasing it above its originally set value introduces memory corruption. --- auto_tests/toxav_basic_test.c | 2 +- toxav/codec.c | 25 +++++++++++++++---------- toxav/codec.h | 3 +++ toxav/toxav.c | 11 ++++++----- toxav/toxav.h | 4 ++-- 5 files changed, 27 insertions(+), 18 deletions(-) diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c index a1bccd7c..0a710746 100644 --- a/auto_tests/toxav_basic_test.c +++ b/auto_tests/toxav_basic_test.c @@ -199,7 +199,7 @@ START_TEST(test_AV_flows) printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time); muhcaps = av_DefaultSettings; - muhcaps.video_height = muhcaps.video_width = 128; + muhcaps.max_video_height = muhcaps.max_video_width = 128; Status status_control = { {none, toxav_new(Alice, 1), NULL, -1}, diff --git a/toxav/codec.c b/toxav/codec.c index ed0c8e54..595c0359 100644 --- a/toxav/codec.c +++ b/toxav/codec.c @@ -217,6 +217,9 @@ int reconfigure_video_encoder_resolution(CodecState *cs, uint16_t width, uint16_ if (cfg.g_w == width && cfg.g_h == height) return 0; + if (width * height > cs->max_width * cs->max_height) + return -1; + LOGGER_DEBUG("New video resolution: %u %u", width, height); cfg.g_w = width; cfg.g_h = height; @@ -249,7 +252,7 @@ int reconfigure_video_encoder_bitrate(CodecState *cs, uint32_t video_bitrate) return 0; } -int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t video_bitrate) +int init_video_encoder(CodecState *cs, uint16_t max_width, uint16_t max_height, uint32_t video_bitrate) { vpx_codec_enc_cfg_t cfg; int rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0); @@ -260,13 +263,18 @@ int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t } cfg.rc_target_bitrate = video_bitrate; - cfg.g_w = 8192; - cfg.g_h = 8192; + cfg.g_w = max_width; + cfg.g_h = max_height; cfg.g_pass = VPX_RC_ONE_PASS; cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS; cfg.g_lag_in_frames = 0; cfg.kf_min_dist = 0; cfg.kf_max_dist = 300; + cfg.kf_mode = VPX_KF_AUTO; + + cs->max_width = max_width; + cs->max_height = max_height; + cs->bitrate = video_bitrate; rc = vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION); @@ -282,9 +290,6 @@ int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t return -1; } - if (reconfigure_video_encoder_resolution(cs, width, height) != 0) - return -1; - return 0; } @@ -322,8 +327,8 @@ CodecState *codec_init_session ( uint32_t audio_bitrate, uint32_t audio_sample_rate, uint32_t audio_channels, uint32_t audio_VAD_tolerance_ms, - uint16_t video_width, - uint16_t video_height, + uint16_t max_video_width, + uint16_t max_video_height, uint32_t video_bitrate ) { CodecState *retu = calloc(sizeof(CodecState), 1); @@ -334,11 +339,11 @@ CodecState *codec_init_session ( uint32_t audio_bitrate, retu->audio_sample_rate = audio_sample_rate; /* Encoders */ - if (!video_width || !video_height) { /* Disable video */ + if (!max_video_width || !max_video_height) { /* Disable video */ /*video_width = 320; video_height = 240; */ } else { - retu->capabilities |= ( 0 == init_video_encoder(retu, video_width, video_height, video_bitrate) ) ? v_encoding : 0; + retu->capabilities |= ( 0 == init_video_encoder(retu, max_video_width, max_video_height, video_bitrate) ) ? v_encoding : 0; retu->capabilities |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0; } diff --git a/toxav/codec.h b/toxav/codec.h index d8e9f1a7..a464ec8f 100644 --- a/toxav/codec.h +++ b/toxav/codec.h @@ -56,6 +56,9 @@ typedef struct _CodecState { /* video decoding */ vpx_codec_ctx_t v_decoder; + int bitrate; + int max_width; + int max_height; /* audio encoding */ OpusEncoder *audio_encoder; diff --git a/toxav/toxav.c b/toxav/toxav.c index 9a1c5e3e..606f1370 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -81,8 +81,8 @@ struct _ToxAv { const ToxAvCodecSettings av_DefaultSettings = { 500, - 800, - 600, + 1280, + 720, 64000, 20, @@ -350,8 +350,8 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin codec_settings->audio_sample_rate, codec_settings->audio_channels, codec_settings->audio_VAD_tolerance, - codec_settings->video_width, - codec_settings->video_height, + codec_settings->max_video_width, + codec_settings->max_video_height, codec_settings->video_bitrate) )) { if ( pthread_mutex_init(&call->mutex, NULL) != 0 ) goto error; @@ -642,7 +642,8 @@ inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *d CallSpecific *call = &av->calls[call_index]; pthread_mutex_lock(&call->mutex); - reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h); + if (reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h) != 0) + return ErrorInternal; int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US); diff --git a/toxav/toxav.h b/toxav/toxav.h index 2e71c4da..b7659441 100644 --- a/toxav/toxav.h +++ b/toxav/toxav.h @@ -120,8 +120,8 @@ typedef enum { */ typedef struct _ToxAvCodecSettings { uint32_t video_bitrate; /* In kbits/s */ - uint16_t video_width; /* In px */ - uint16_t video_height; /* In px */ + uint16_t max_video_width; /* In px */ + uint16_t max_video_height; /* In px */ uint32_t audio_bitrate; /* In bits/s */ uint16_t audio_frame_duration; /* In ms */ From d8406db1133a66d9183c2eade9e4fe0f9f22dd73 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Sat, 5 Jul 2014 19:47:13 -0400 Subject: [PATCH 05/50] delete groupchat when join fails --- toxcore/Messenger.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 2adbd870..b65f09ae 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -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; } From dfa483ba0d440519b044f831b3349a562df003e0 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 5 Jul 2014 21:49:47 -0400 Subject: [PATCH 06/50] Fixed msi_session being used after being freed. --- toxav/toxav.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toxav/toxav.c b/toxav/toxav.c index 81196af9..151a1e64 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -133,8 +133,6 @@ ToxAv *toxav_new( Tox *messenger, int32_t max_calls) */ void toxav_kill ( ToxAv *av ) { - msi_terminate_session(av->msi_session); - int i = 0; for (; i < av->max_calls; i ++) { @@ -152,6 +150,8 @@ void toxav_kill ( ToxAv *av ) if ( av->calls[i].cs ) codec_terminate_session(av->calls[i].cs); } + msi_terminate_session(av->msi_session); + free(av->calls); free(av); } From a13bc5e70c097c1c0a02b25c86a603d9b400f3ec Mon Sep 17 00:00:00 2001 From: kyle condon Date: Sun, 6 Jul 2014 09:55:46 +0100 Subject: [PATCH 07/50] Update ping_array.c Change calloc call on line 138 from empty_array->entries = calloc(size * sizeof(Ping_Array_Entry), 1);, to empty_array->entries = calloc(size, sizeof(Ping_Array_Entry)); --- toxcore/ping_array.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxcore/ping_array.c b/toxcore/ping_array.c index 5c92527e..93dade05 100644 --- a/toxcore/ping_array.c +++ b/toxcore/ping_array.c @@ -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; From f9f3a810c074e4c0a36faefa07ad8001b6a23901 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sun, 6 Jul 2014 13:29:25 -0400 Subject: [PATCH 08/50] Typo fix. --- toxcore/tox.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxcore/tox.h b/toxcore/tox.h index 5418b03e..d931b9be 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -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. From 35813b41b10f7f18c9f77ffa68cb8e6dc0fe1337 Mon Sep 17 00:00:00 2001 From: toxxxer Date: Sun, 6 Jul 2014 23:54:13 +0200 Subject: [PATCH 09/50] Update for OS X build instruction --- INSTALL.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/INSTALL.md b/INSTALL.md index 6cdec95b..41aa5afd 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -183,6 +183,12 @@ If after running ./configure you get an error about core being unable to find li 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 +``` + ###Windows: From 3d4de767fe8fefb5eb2456674be9930388564ee8 Mon Sep 17 00:00:00 2001 From: notsecure Date: Mon, 7 Jul 2014 16:10:10 -0400 Subject: [PATCH 10/50] use callbacks for a/v --- toxav/rtp.c | 132 +------------------ toxav/rtp.h | 10 +- toxav/toxav.c | 347 +++++++++++++++++--------------------------------- toxav/toxav.h | 43 +++---- 4 files changed, 136 insertions(+), 396 deletions(-) diff --git a/toxav/rtp.c b/toxav/rtp.c index 653a22df..a6bcaf18 100644 --- a/toxav/rtp.c +++ b/toxav/rtp.c @@ -28,6 +28,7 @@ #include "rtp.h" #include +void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg); #define size_32 4 @@ -372,11 +373,6 @@ int rtp_handle_packet ( void *object, const uint8_t *data, uint32_t length ) return -1; } - if ( _session->queue_limit <= _session->queue_size ) { - LOGGER_WARNING("Queue limit reached!"); - return -1; - } - _msg = msg_parse ( data + 1, length - 1 ); if ( !_msg ) { @@ -390,18 +386,7 @@ int rtp_handle_packet ( void *object, const uint8_t *data, uint32_t length ) _session->timestamp = _msg->header->timestamp; } - pthread_mutex_lock(&_session->mutex); - - if ( _session->last_msg ) { - _session->last_msg->next = _msg; - _session->last_msg = _msg; - } else { - _session->last_msg = _session->oldest_msg = _msg; - } - - _session->queue_size++; - - pthread_mutex_unlock(&_session->mutex); + toxav_handle_packet(_session, _msg); return 0; } @@ -467,105 +452,6 @@ RTPMessage *rtp_new_message ( RTPSession *session, const uint8_t *data, uint32_t } - -/** - * @brief Release all messages held by session. - * - * @param session The session. - * @return int - * @retval -1 Error occurred. - * @retval 0 Success. - */ -int rtp_release_session_recv ( RTPSession *session ) -{ - if ( !session ) { - LOGGER_WARNING("No session!"); - return -1; - } - - RTPMessage *_tmp, * _it; - - pthread_mutex_lock(&session->mutex); - - for ( _it = session->oldest_msg; _it; _it = _tmp ) { - _tmp = _it->next; - rtp_free_msg( session, _it); - } - - session->last_msg = session->oldest_msg = NULL; - session->queue_size = 0; - - pthread_mutex_unlock(&session->mutex); - - return 0; -} - - -/** - * @brief Call this to change queue limit - * - * @param session The session - * @param limit new limit - * @return void - */ -void rtp_queue_adjust_limit(RTPSession *session, uint64_t limit) -{ - pthread_mutex_lock(&session->mutex); - - RTPMessage *_tmp, * _it = session->oldest_msg; - - for ( ; session->queue_size > limit; _it = _tmp ) { - _tmp = _it->next; - rtp_free_msg( session, _it); - session->queue_size --; - } - - session->oldest_msg = _it; - session->queue_limit = limit; - - pthread_mutex_unlock(&session->mutex); -} - - -/** - * @brief Gets oldest message in the list. - * - * @param session Where the list is. - * @return RTPMessage* The message. You _must_ call rtp_msg_free() to free it. - * @retval NULL No messages in the list, or no list. - */ -RTPMessage *rtp_recv_msg ( RTPSession *session ) -{ - if ( !session ) { - LOGGER_WARNING("No session!"); - return NULL; - } - - pthread_mutex_lock(&session->mutex); - - if ( session->queue_size == 0 ) { - pthread_mutex_unlock(&session->mutex); - return NULL; - } - - - RTPMessage *_retu = session->oldest_msg; - - /*if (_retu)*/ - session->oldest_msg = _retu->next; - - if ( !session->oldest_msg ) - session->last_msg = NULL; - - session->queue_size --; - - pthread_mutex_unlock(&session->mutex); - - - return _retu; -} - - /** * @brief Sends data to _RTPSession::dest * @@ -627,7 +513,6 @@ void rtp_free_msg ( RTPSession *session, RTPMessage *msg ) free ( msg ); } - /** * @brief Must be called before calling any other rtp function. It's used * to initialize RTP control session. @@ -682,11 +567,6 @@ RTPSession *rtp_init_session ( int payload_type, Messenger *messenger, int frien /* Also set payload type as prefix */ _retu->prefix = payload_type; - _retu->oldest_msg = _retu->last_msg = NULL; - _retu->queue_limit = 100; /* Default */ - _retu->queue_size = 0; - - pthread_mutex_init(&_retu->mutex, NULL); /* * */ @@ -709,17 +589,9 @@ void rtp_terminate_session ( RTPSession *session, Messenger *messenger ) custom_lossy_packet_registerhandler(messenger, session->dest, session->prefix, NULL, NULL); - rtp_release_session_recv(session); - - pthread_mutex_lock(&session->mutex); - free ( session->ext_header ); free ( session->csrc ); - pthread_mutex_unlock(&session->mutex); - - pthread_mutex_destroy(&session->mutex); - LOGGER_DEBUG("Terminated RTP session: %p", session); /* And finally free session */ diff --git a/toxav/rtp.h b/toxav/rtp.h index 727839c6..45128285 100644 --- a/toxav/rtp.h +++ b/toxav/rtp.h @@ -105,17 +105,12 @@ typedef struct _RTPSession { */ RTPExtHeader *ext_header; - RTPMessage *oldest_msg; - RTPMessage *last_msg; /* tail */ - - uint64_t queue_limit;/* Default 100; modify per thy liking */ - uint64_t queue_size; /* currently holding << messages */ - /* Msg prefix for core to know when recving */ uint8_t prefix; - pthread_mutex_t mutex; int dest; + int32_t call_index; + struct _ToxAv *av; } RTPSession; @@ -172,7 +167,6 @@ int rtp_send_msg ( RTPSession *session, Messenger *messenger, const uint8_t *dat */ void rtp_free_msg ( RTPSession *session, RTPMessage *msg ); - /** * @brief Must be called before calling any other rtp function. It's used * to initialize RTP control session. diff --git a/toxav/toxav.c b/toxav/toxav.c index 151a1e64..38114ad1 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -76,6 +76,10 @@ struct _ToxAv { Messenger *messenger; MSISession *msi_session; /** Main msi session */ CallSpecific *calls; /** Per-call params */ + + void (*audio_callback)(ToxAv*, int32_t, int16_t*, int); + void (*video_callback)(ToxAv*, int32_t, vpx_image_t*); + uint32_t max_calls; }; @@ -168,6 +172,28 @@ void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID msi_register_callback((MSICallback)callback, (MSICallbackID) id, userdata); } +/** + * @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)) +{ + av->audio_callback = callback; +} + +/** + * @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*)) +{ + av->video_callback = callback; +} + /** * @brief Call user. Use its friend_id. * @@ -316,17 +342,21 @@ int toxav_prepare_transmission ( ToxAv *av, int32_t call_index, ToxAvCodecSettin return ErrorInternal; } + call->crtps[audio_index]->call_index = call_index; + call->crtps[audio_index]->av = av; if ( support_video ) { call->crtps[video_index] = rtp_init_session(type_video, av->messenger, av->msi_session->calls[call_index]->peers[0]); - if ( !call->crtps[video_index] ) { LOGGER_ERROR("Error while starting video RTP session!\n"); goto error; } + call->crtps[video_index]->call_index = call_index; + call->crtps[video_index]->av = av; + call->frame_limit = 0; call->frame_id = 0; call->frame_outid = 0; @@ -474,140 +504,6 @@ inline__ int toxav_send_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallTy } } -/** - * @brief Receive RTP payload. - * - * @param av Handler. - * @param type Type of the payload. - * @param dest Storage. - * @return int - * @retval ToxAvError On Error. - * @retval >=0 Size of received payload. - */ -inline__ int toxav_recv_rtp_payload ( ToxAv *av, int32_t call_index, ToxAvCallType type, uint8_t *dest ) -{ - if ( !dest ) return ErrorInternal; - - CallSpecific *call = &av->calls[call_index]; - - if ( !call->crtps[type - TypeAudio] ) return ErrorNoRtpSession; - - RTPMessage *message; - - if ( type == TypeAudio ) { - - do { - message = rtp_recv_msg(call->crtps[audio_index]); - - if (message) { - /* push the packet into the queue */ - queue(call->j_buf, message); - } - } while (message); - - int success = 0; - message = dequeue(call->j_buf, &success); - - if ( success == 2) return ErrorAudioPacketLost; - } else { - message = rtp_recv_msg(call->crtps[video_index]); - } - - if ( message ) { - memcpy(dest, message->data, message->length); - - int length = message->length; - - rtp_free_msg(NULL, message); - - return length; - } - - return 0; -} - -/** - * @brief Receive decoded video packet. - * - * @param av Handler. - * @param output Storage. - * @return int - * @retval 0 Success. - * @retval ToxAvError On Error. - */ -inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **output) -{ - if ( !output ) return ErrorInternal; - - if (cii(call_index, av->msi_session)) { - LOGGER_WARNING("Invalid call index: %d", call_index); - return ErrorNoCall; - } - - CallSpecific *call = &av->calls[call_index]; - pthread_mutex_lock(&call->mutex); - - if (!call->call_active) { - pthread_mutex_unlock(&call->mutex); - LOGGER_WARNING("Action on inactive call: %d", call_index); - return ErrorNoCall; - } - - uint8_t packet [RTP_PAYLOAD_SIZE]; - int recved_size; - - while ((recved_size = toxav_recv_rtp_payload(av, call_index, TypeVideo, packet)) > 0) { - if (recved_size < VIDEOFRAME_HEADER_SIZE) { - continue; - } - - uint8_t i = packet[0] - call->frame_id; - - if (i == 0) { - /* 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); - call->frame_id = packet[0]; - memset(call->frame_buf, 0, call->frame_limit); - call->frame_limit = 0; - - if (rc != VPX_CODEC_OK) { - LOGGER_ERROR("Error decoding video: %u %s\n", i, vpx_codec_err_to_string(rc)); - } - } else { - /* old packet, dont read */ - LOGGER_DEBUG("Old packet: %u\n", i); - continue; - } - - if (packet[1] > (MAX_VIDEOFRAME_SIZE - VIDEOFRAME_PIECE_SIZE + 1) / - VIDEOFRAME_PIECE_SIZE) { //TODO, fix this check? not sure - /* packet out of buffer range */ - continue; - } - - LOGGER_DEBUG("Video Packet: %u %u\n", packet[0], packet[1]); - memcpy(call->frame_buf + packet[1] * VIDEOFRAME_PIECE_SIZE, packet + VIDEOFRAME_HEADER_SIZE, - recved_size - VIDEOFRAME_HEADER_SIZE); - uint32_t limit = packet[1] * VIDEOFRAME_PIECE_SIZE + recved_size - VIDEOFRAME_HEADER_SIZE; - - if (limit > call->frame_limit) { - call->frame_limit = limit; - LOGGER_DEBUG("Limit: %u\n", call->frame_limit); - } - } - - vpx_codec_iter_t iter = NULL; - vpx_image_t *img; - img = vpx_codec_get_frame(&call->cs->v_decoder, &iter); - - *output = img; - - pthread_mutex_unlock(&call->mutex); - return ErrorNone; -} - /** * @brief Encode and send video packet. * @@ -703,67 +599,6 @@ inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *d return copied; } -/** - * @brief Receive decoded audio frame. - * - * @param av Handler. - * @param frame_size The size of dest in frames/samples (one frame/sample is 16 bits or 2 bytes - * and corresponds to one sample of audio.) - * @param dest Destination of the raw audio (16 bit signed pcm with AUDIO_CHANNELS channels). - * Make sure it has enough space for frame_size frames/samples. - * @return int - * @retval >=0 Size of received data in frames/samples. - * @retval ToxAvError On error. - */ -inline__ int toxav_recv_audio ( ToxAv *av, int32_t call_index, int frame_size, int16_t *dest ) -{ - if ( !dest ) return ErrorInternal; - - if (cii(call_index, av->msi_session)) { - LOGGER_WARNING("Invalid call index: %d", call_index); - return ErrorNoCall; - } - - - CallSpecific *call = &av->calls[call_index]; - pthread_mutex_lock(&call->mutex); - - - if (!call->call_active) { - pthread_mutex_unlock(&call->mutex); - LOGGER_WARNING("Action on inactive call: %d", call_index); - return ErrorNoCall; - } - - uint8_t packet [RTP_PAYLOAD_SIZE]; - - int recved_size = toxav_recv_rtp_payload(av, call_index, TypeAudio, packet); - - if ( recved_size == ErrorAudioPacketLost ) { - int dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1); - - pthread_mutex_unlock(&call->mutex); - - if ( dec_size < 0 ) { - LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); - return ErrorInternal; - } else return dec_size; - - } else if ( recved_size ) { - int dec_size = opus_decode(call->cs->audio_decoder, packet, recved_size, dest, frame_size, 0); - - pthread_mutex_unlock(&call->mutex); - - if ( dec_size < 0 ) { - LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); - return ErrorInternal; - } else return dec_size; - } else { - pthread_mutex_unlock(&call->mutex); - return 0; /* Nothing received */ - } -} - /** * @brief Send audio frame. * @@ -905,42 +740,6 @@ inline__ int toxav_capability_supported ( ToxAv *av, int32_t call_index, ToxAvCa /* 0 is error here */ } -/** - * @brief Set queue limit - * - * @param av Handler - * @param call_index index - * @param limit the limit - * @return void - */ -inline__ int toxav_set_audio_queue_limit(ToxAv *av, int32_t call_index, uint64_t limit) -{ - if ( av->calls[call_index].crtps[audio_index] ) - rtp_queue_adjust_limit(av->calls[call_index].crtps[audio_index], limit); - else - return ErrorNoRtpSession; - - return ErrorNone; -} - -/** - * @brief Set queue limit - * - * @param av Handler - * @param call_index index - * @param limit the limit - * @return void - */ -inline__ int toxav_set_video_queue_limit(ToxAv *av, int32_t call_index, uint64_t limit) -{ - if ( av->calls[call_index].crtps[video_index] ) - rtp_queue_adjust_limit(av->calls[call_index].crtps[video_index], limit); - else - return ErrorNoRtpSession; - - return ErrorNone; -} - inline__ Tox *toxav_get_tox(ToxAv *av) { return (Tox *)av->messenger; @@ -952,3 +751,87 @@ int toxav_has_activity(ToxAv *av, int32_t call_index, int16_t *PCM, uint16_t fra return energy_VAD(av->calls[call_index].cs, PCM, frame_size, ref_energy); } + +void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg) +{ + ToxAv *av = _session->av; + int32_t call_index = _session->call_index; + CallSpecific *call = &av->calls[call_index]; + + if(_session->payload_type == type_audio % 128) { + queue(call->j_buf, _msg); + + int success = 0, dec_size; + int frame_size = 960; + int16_t dest[frame_size]; + + while((_msg = dequeue(call->j_buf, &success)) || success == 2) { + if(success == 2) { + dec_size = opus_decode(call->cs->audio_decoder, NULL, 0, dest, frame_size, 1); + } else { + dec_size = opus_decode(call->cs->audio_decoder, _msg->data, _msg->length, dest, frame_size, 0); + rtp_free_msg(NULL, _msg); + } + + if(dec_size < 0) { + LOGGER_WARNING("Decoding error: %s", opus_strerror(dec_size)); + continue; + } + + av->audio_callback(av, call_index, dest, frame_size); + } + } else { + uint8_t *packet = _msg->data; + int recved_size = _msg->length; + + if(recved_size < VIDEOFRAME_HEADER_SIZE) { + goto end; + } + + uint8_t i = packet[0] - call->frame_id; + + if (i == 0) { + /* 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); + call->frame_id = packet[0]; + memset(call->frame_buf, 0, call->frame_limit); + call->frame_limit = 0; + + if (rc != VPX_CODEC_OK) { + LOGGER_ERROR("Error decoding video: %u %s\n", i, vpx_codec_err_to_string(rc)); + } + } else { + /* old packet, dont read */ + LOGGER_DEBUG("Old packet: %u\n", i); + goto end; + } + + if (packet[1] > (MAX_VIDEOFRAME_SIZE - VIDEOFRAME_PIECE_SIZE + 1) / + VIDEOFRAME_PIECE_SIZE) { //TODO, fix this check? not sure + /* packet out of buffer range */ + goto end; + } + + LOGGER_DEBUG("Video Packet: %u %u\n", packet[0], packet[1]); + memcpy(call->frame_buf + packet[1] * VIDEOFRAME_PIECE_SIZE, packet + VIDEOFRAME_HEADER_SIZE, + recved_size - VIDEOFRAME_HEADER_SIZE); + uint32_t limit = packet[1] * VIDEOFRAME_PIECE_SIZE + recved_size - VIDEOFRAME_HEADER_SIZE; + + if (limit > call->frame_limit) { + call->frame_limit = limit; + LOGGER_DEBUG("Limit: %u\n", call->frame_limit); + } + + end:; + vpx_codec_iter_t iter = NULL; + vpx_image_t *img; + img = vpx_codec_get_frame(&call->cs->v_decoder, &iter); + if(img) { + av->video_callback(av, call_index, img); + } + + rtp_free_msg(NULL, _msg); + } +} diff --git a/toxav/toxav.h b/toxav/toxav.h index b7659441..6a35fccf 100644 --- a/toxav/toxav.h +++ b/toxav/toxav.h @@ -164,6 +164,22 @@ void toxav_kill(ToxAv *av); */ void toxav_register_callstate_callback (ToxAVCallback callback, ToxAvCallbackID id, void *userdata); +/** + * @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. * @@ -252,31 +268,6 @@ int toxav_prepare_transmission(ToxAv *av, int32_t call_index, ToxAvCodecSettings */ int toxav_kill_transmission(ToxAv *av, int32_t call_index); -/** - * @brief Receive decoded video packet. - * - * @param av Handler. - * @param output Storage. - * @return int - * @retval 0 Success. - * @retval ToxAvError On Error. - */ -int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **output); - -/** - * @brief Receive decoded audio frame. - * - * @param av Handler. - * @param frame_size The size of dest in frames/samples (one frame/sample is 16 bits or 2 bytes - * and corresponds to one sample of audio.) - * @param dest Destination of the raw audio (16 bit signed pcm with AUDIO_CHANNELS channels). - * Make sure it has enough space for frame_size frames/samples. - * @return int - * @retval >=0 Size of received data in frames/samples. - * @retval ToxAvError On error. - */ -int toxav_recv_audio( ToxAv *av, int32_t call_index, int frame_size, int16_t *dest ); - /** * @brief Encode and send video packet. * @@ -399,4 +390,4 @@ int toxav_has_activity ( ToxAv *av, int32_t call_index, int16_t *PCM, uint16_t f } #endif -#endif /* __TOXAV */ \ No newline at end of file +#endif /* __TOXAV */ From c527979daa5b65ec9a838c1b3fe998af6375953a Mon Sep 17 00:00:00 2001 From: notsecure Date: Mon, 7 Jul 2014 17:37:05 -0400 Subject: [PATCH 11/50] make autotests compile --- auto_tests/toxav_basic_test.c | 48 ++++++++++++++++++++++------------- auto_tests/toxav_many_test.c | 28 ++++++++++++++------ 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c index 0a710746..bf130ecb 100644 --- a/auto_tests/toxav_basic_test.c +++ b/auto_tests/toxav_basic_test.c @@ -138,6 +138,15 @@ void callback_requ_timeout ( int32_t call_index, void *_arg ) { ck_assert_msg(0, "No answer!"); } + +static void callback_audio(ToxAv *av, int32_t call_index, int16_t *data, int length) +{ +} + +static void callback_video(ToxAv *av, int32_t call_index, vpx_image_t *img) +{ +} + /*************************************************************************************************/ /* Alice calls bob and the call starts. @@ -222,6 +231,10 @@ START_TEST(test_AV_flows) toxav_register_callstate_callback(callback_recv_error, av_OnError, &status_control); toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, &status_control); + toxav_register_audio_recv_callback(status_control.Alice.av, callback_audio); + toxav_register_video_recv_callback(status_control.Alice.av, callback_video); + toxav_register_audio_recv_callback(status_control.Bob.av, callback_audio); + toxav_register_video_recv_callback(status_control.Bob.av, callback_video); const int frame_size = (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000); int16_t sample_payload[frame_size]; @@ -267,21 +280,22 @@ START_TEST(test_AV_flows) toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size); /* Both receive */ - int16_t storage[frame_size]; + /*int16_t storage[frame_size]; int recved; /* Payload from Bob */ - recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage); + + /*recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage); if ( recved ) { - /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");*/ + //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid"); } recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage); if ( recved ) { - /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");*/ - } + //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid"); + }*/ if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ step++; /* This terminates the loop */ @@ -326,11 +340,11 @@ START_TEST(test_AV_flows) int recved; /* Payload from Bob */ - recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage); + /*recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage); if ( recved ) { - /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");*/ - } + //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid"); + }*/ /* Video payload */ // toxav_recv_video(status_control.Alice.av, status_control.Alice.call_index, &video_storage); @@ -346,11 +360,11 @@ START_TEST(test_AV_flows) /* Payload from Alice */ - recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage); + /*recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage); if ( recved ) { - /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");*/ - } + //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid"); + }*/ if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ step++; /* This terminates the loop */ @@ -397,11 +411,11 @@ START_TEST(test_AV_flows) int recved; /* Payload from Bob */ - recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage); + /*recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage); if ( recved ) { - /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");*/ - } + //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid"); + }*/ /* Video payload */ // toxav_recv_video(status_control.Alice.av, status_control.Alice.call_index, &video_storage); @@ -417,11 +431,11 @@ START_TEST(test_AV_flows) /* Payload from Alice */ - recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage); + /*recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage); if ( recved ) { - /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");*/ - } + ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid"); + }*/ /* Video payload */ // toxav_recv_video(status_control.Bob.av, status_control.Bob.call_index, &video_storage); diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c index 2a931cb0..106d2f32 100644 --- a/auto_tests/toxav_many_test.c +++ b/auto_tests/toxav_many_test.c @@ -124,6 +124,14 @@ void callback_requ_timeout ( int32_t call_index, void *_arg ) { ck_assert_msg(0, "No answer!"); } + +static void callback_audio(ToxAv *av, int32_t call_index, int16_t *data, int length) +{ +} + +static void callback_video(ToxAv *av, int32_t call_index, vpx_image_t *img) +{ +} /*************************************************************************************************/ @@ -142,6 +150,11 @@ void *in_thread_call (void *arg) uint8_t prepared_payload[RTP_PAYLOAD_SIZE]; + toxav_register_audio_recv_callback(this_call->Caller.av, callback_audio); + toxav_register_video_recv_callback(this_call->Caller.av, callback_video); + toxav_register_audio_recv_callback(this_call->Callee.av, callback_audio); + toxav_register_video_recv_callback(this_call->Callee.av, callback_video); + /* NOTE: CALLEE WILL ALWAHYS NEED CALL_IDX == 0 */ while (running) { @@ -192,18 +205,18 @@ void *in_thread_call (void *arg) int recved; /* Payload from CALLER */ - recved = toxav_recv_audio(this_call->Callee.av, 0, frame_size, storage); + /*recved = toxav_recv_audio(this_call->Callee.av, 0, frame_size, storage); if ( recved ) { - /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLER is invalid");*/ - } + //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLER is invalid"); + }*/ /* Payload from CALLEE */ - recved = toxav_recv_audio(this_call->Caller.av, call_idx, frame_size, storage); + /*recved = toxav_recv_audio(this_call->Caller.av, call_idx, frame_size, storage); if ( recved ) { - /*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLEE is invalid");*/ - } + //ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLEE is invalid"); + }*/ c_sleep(20); } @@ -335,7 +348,6 @@ START_TEST(test_AV_three_calls) toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, &status_control); - for ( i = 0; i < 3; i++ ) pthread_create(&status_control.calls[i].tid, NULL, in_thread_call, &status_control.calls[i]); @@ -403,4 +415,4 @@ int main(int argc, char *argv[]) // test_AV_three_calls(); // // return 0; -} \ No newline at end of file +} From b90ecb377d59384770a594abc5c5e3022e99adc8 Mon Sep 17 00:00:00 2001 From: notsecure Date: Mon, 7 Jul 2014 18:47:49 -0400 Subject: [PATCH 12/50] locks in test --- auto_tests/toxav_many_test.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c index 106d2f32..3195d1ed 100644 --- a/auto_tests/toxav_many_test.c +++ b/auto_tests/toxav_many_test.c @@ -24,6 +24,7 @@ #define c_sleep(x) usleep(1000*x) #endif +pthread_mutex_t muhmutex; typedef enum _CallStatus { none, @@ -223,8 +224,10 @@ void *in_thread_call (void *arg) step++; /* This terminates the loop */ + pthread_mutex_lock(&muhmutex); toxav_kill_transmission(this_call->Callee.av, 0); toxav_kill_transmission(this_call->Caller.av, call_idx); + pthread_mutex_unlock(&muhmutex); /* Call over CALLER hangs up */ toxav_hangup(this_call->Caller.av, call_idx); @@ -348,6 +351,9 @@ START_TEST(test_AV_three_calls) toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, &status_control); + pthread_mutex_init(&muhmutex, NULL); + + for ( i = 0; i < 3; i++ ) pthread_create(&status_control.calls[i].tid, NULL, in_thread_call, &status_control.calls[i]); @@ -362,11 +368,15 @@ START_TEST(test_AV_three_calls) status_control.calls[1].Callee.status != Ended && status_control.calls[1].Caller.status != Ended && status_control.calls[2].Callee.status != Ended && status_control.calls[2].Caller.status != Ended ) { + pthread_mutex_lock(&muhmutex); + tox_do(bootstrap_node); tox_do(caller); tox_do(callees[0]); tox_do(callees[1]); tox_do(callees[2]); + + pthread_mutex_unlock(&muhmutex); c_sleep(20); } From b4f43b4222eb033ee9af940641a00535f6091e95 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Mon, 7 Jul 2014 19:49:01 -0400 Subject: [PATCH 13/50] Fixed overflow bug. --- toxcore/group_chats.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 1f76878b..53ef69d3 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -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; } From 95d737cb5f16df4d22eecc2a947b4e9689be754e Mon Sep 17 00:00:00 2001 From: irungentoo Date: Mon, 7 Jul 2014 23:19:56 -0400 Subject: [PATCH 14/50] Fixed segfault and other possible bugs in msi.c toxav should no longer have weird behaviour when a dead call times out. --- toxav/msi.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/toxav/msi.c b/toxav/msi.c index 999f86b6..6409b314 100644 --- a/toxav/msi.c +++ b/toxav/msi.c @@ -538,8 +538,9 @@ GENERIC_SETTER_DEFINITION ( callid ) typedef struct _Timer { - void *(*func)(void *); - void *func_args; + void *(*func)(void *, int); + void *func_arg1; + int func_arg2; uint64_t timeout; size_t idx; @@ -567,7 +568,7 @@ typedef struct _TimerHandler { * @param timeout Timeout in ms * @return int */ -int timer_alloc ( TimerHandler *timers_container, void *(func)(void *), void *arg, unsigned timeout) +int timer_alloc ( TimerHandler *timers_container, void *(func)(void *, int), void *arg1, int arg2, unsigned timeout) { pthread_mutex_lock(&timers_container->mutex); @@ -592,7 +593,8 @@ int timer_alloc ( TimerHandler *timers_container, void *(func)(void *), void *ar timers_container->size ++; timer->func = func; - timer->func_args = arg; + timer->func_arg1 = arg1; + timer->func_arg2 = arg2; timer->timeout = timeout + current_time_monotonic(); /* In ms */ timer->idx = i; @@ -672,15 +674,9 @@ void *timer_poll( void *arg ) uint64_t time = current_time_monotonic(); - while ( handler->timers[0] && handler->timers[0]->timeout < time ) { - - pthread_t _tid; - - if ( 0 != pthread_create(&_tid, NULL, handler->timers[0]->func, handler->timers[0]->func_args) || - 0 != pthread_detach(_tid) ) - LOGGER_ERROR("Failed to execute timer at: %d!", handler->timers[0]->timeout); - - else LOGGER_DEBUG("Exectued timer assigned at: %d", handler->timers[0]->timeout); + if ( handler->timers[0] && handler->timers[0]->timeout < time ) { + handler->timers[0]->func(handler->timers[0]->func_arg1, handler->timers[0]->func_arg2); + LOGGER_DEBUG("Exectued timer assigned at: %d", handler->timers[0]->timeout); timer_release(handler, 0); } @@ -1142,18 +1138,20 @@ int terminate_call ( MSISession *session, MSICall *call ) * @param arg Control session * @return void* */ -void *handle_timeout ( void *arg ) +void *handle_timeout ( void *arg1, int arg2 ) { /* TODO: Cancel might not arrive there; set up * timers on these cancels and terminate call on * their timeout */ - MSICall *_call = arg; + int call_index = arg2; + MSISession *session = arg1; + MSICall *_call = session->calls[call_index]; if (_call) { LOGGER_DEBUG("[Call: %s] Request timed out!", _call->id); - invoke_callback(_call->call_idx, MSI_OnRequestTimeout); + invoke_callback(call_index, MSI_OnRequestTimeout); } if ( _call && _call->session ) { @@ -1347,7 +1345,8 @@ int handle_recv_ringing ( MSISession *session, MSICall *call, MSIMessage *msg ) LOGGER_DEBUG("Session: %p Handling 'ringing' on call: %s", session, call->id ); - call->ringing_timer_id = timer_alloc ( session->timer_handler, handle_timeout, call, call->ringing_tout_ms ); + call->ringing_timer_id = timer_alloc ( session->timer_handler, handle_timeout, session, call->call_idx, + call->ringing_tout_ms ); pthread_mutex_unlock(&session->mutex); @@ -1725,7 +1724,7 @@ int msi_invite ( MSISession *session, int32_t *call_index, MSICallType call_type _call->state = call_inviting; - _call->request_timer_id = timer_alloc ( session->timer_handler, handle_timeout, _call, m_deftout ); + _call->request_timer_id = timer_alloc ( session->timer_handler, handle_timeout, session, _call->call_idx, m_deftout ); LOGGER_DEBUG("Invite sent"); @@ -1774,7 +1773,7 @@ int msi_hangup ( MSISession *session, int32_t call_index ) free_message ( _msg_end ); session->calls[call_index]->request_timer_id = - timer_alloc ( session->timer_handler, handle_timeout, session->calls[call_index], m_deftout ); + timer_alloc ( session->timer_handler, handle_timeout, session, call_index, m_deftout ); pthread_mutex_unlock(&session->mutex); return 0; @@ -1850,7 +1849,7 @@ int msi_cancel ( MSISession *session, int32_t call_index, uint32_t peer, const c free_message ( _msg_cancel ); /*session->calls[call_index]->state = call_hanged_up; - session->calls[call_index]->request_timer_id = timer_alloc ( handle_timeout, session->calls[call_index], m_deftout );*/ + session->calls[call_index]->request_timer_id = timer_alloc ( handle_timeout, session, call_index, m_deftout );*/ terminate_call ( session, session->calls[call_index] ); pthread_mutex_unlock(&session->mutex); @@ -1887,7 +1886,7 @@ int msi_reject ( MSISession *session, int32_t call_index, const uint8_t *reason session->calls[call_index]->state = call_hanged_up; session->calls[call_index]->request_timer_id = - timer_alloc ( session->timer_handler, handle_timeout, session->calls[call_index], m_deftout ); + timer_alloc ( session->timer_handler, handle_timeout, session, call_index, m_deftout ); pthread_mutex_unlock(&session->mutex); return 0; From 2772bffeebcda9c1947c9855fc4ad42ddb32cbea Mon Sep 17 00:00:00 2001 From: irungentoo Date: Tue, 8 Jul 2014 10:38:48 -0400 Subject: [PATCH 15/50] Fixed possible out of bounds read. --- toxcore/onion_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index 7d0efc79..42982ea8 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -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; } From 9874173d71969792330d8fbc612bee6093100e60 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Tue, 8 Jul 2014 11:51:27 -0400 Subject: [PATCH 16/50] Fixed deadlock. --- toxav/msi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/toxav/msi.c b/toxav/msi.c index 6409b314..3497f4e7 100644 --- a/toxav/msi.c +++ b/toxav/msi.c @@ -1162,8 +1162,6 @@ void *handle_timeout ( void *arg1, int arg2 ) msi_cancel ( _call->session, _call->call_idx, _call->peers [0], "Request timed out" ); /*terminate_call(_call->session, _call);*/ } - - pthread_exit(NULL); } From 7ce9816e40cdfc448b6306839948bceffb38dd32 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Tue, 8 Jul 2014 12:04:13 -0400 Subject: [PATCH 17/50] Fixed threading bug that could cause segfaults. --- toxav/msi.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/toxav/msi.c b/toxav/msi.c index 3497f4e7..1219c64a 100644 --- a/toxav/msi.c +++ b/toxav/msi.c @@ -620,18 +620,20 @@ int timer_alloc ( TimerHandler *timers_container, void *(func)(void *, int), voi * * @param timers_container handler * @param idx index + * @param idx lock_mutex (does the mutex need to be locked) * @return int */ -int timer_release ( TimerHandler *timers_container, int idx ) +int timer_release ( TimerHandler *timers_container, int idx , int lock_mutex) { - int rc = pthread_mutex_trylock(&timers_container->mutex); + if (lock_mutex) + pthread_mutex_lock(&timers_container->mutex); Timer **timed_events = timers_container->timers; if (!timed_events[idx]) { LOGGER_WARNING("No event under index: %d", idx); - if ( rc != EBUSY ) pthread_mutex_unlock(&timers_container->mutex); + if (lock_mutex) pthread_mutex_unlock(&timers_container->mutex); return -1; } @@ -651,7 +653,7 @@ int timer_release ( TimerHandler *timers_container, int idx ) LOGGER_DEBUG("Popped index: %d, current size: %d ", idx, timers_container->size); - if ( rc != EBUSY ) pthread_mutex_unlock(&timers_container->mutex); + if (lock_mutex) pthread_mutex_unlock(&timers_container->mutex); return 0; } @@ -678,7 +680,7 @@ void *timer_poll( void *arg ) handler->timers[0]->func(handler->timers[0]->func_arg1, handler->timers[0]->func_arg2); LOGGER_DEBUG("Exectued timer assigned at: %d", handler->timers[0]->timeout); - timer_release(handler, 0); + timer_release(handler, 0, 0); } } @@ -1107,8 +1109,8 @@ int terminate_call ( MSISession *session, MSICall *call ) * NOTE: This has to be done before possibly * locking the mutex the second time */ - timer_release ( session->timer_handler, call->request_timer_id ); - timer_release ( session->timer_handler, call->ringing_timer_id ); + timer_release ( session->timer_handler, call->request_timer_id, 1); + timer_release ( session->timer_handler, call->ringing_timer_id, 1); /* Get a handle */ pthread_mutex_lock ( &call->mutex ); @@ -1371,7 +1373,7 @@ int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage *msg ) flush_peer_type ( call, msg, 0 ); - timer_release ( session->timer_handler, call->ringing_timer_id ); + timer_release ( session->timer_handler, call->ringing_timer_id, 1 ); pthread_mutex_unlock(&session->mutex); invoke_callback(call->call_idx, MSI_OnStarting); @@ -1389,7 +1391,7 @@ int handle_recv_ending ( MSISession *session, MSICall *call, MSIMessage *msg ) LOGGER_DEBUG("Session: %p Handling 'ending' on call: %s", session, call->id ); /* Stop timer */ - timer_release ( session->timer_handler, call->request_timer_id ); + timer_release ( session->timer_handler, call->request_timer_id, 1 ); pthread_mutex_unlock(&session->mutex); @@ -1531,7 +1533,7 @@ void msi_handle_packet ( Messenger *messenger, int source, const uint8_t *data, } /* Got response so cancel timer */ - if ( call ) timer_release ( session->timer_handler, call->request_timer_id ); + if ( call ) timer_release ( session->timer_handler, call->request_timer_id, 1 ); uint8_t _response_value[32]; From bd4c142e38afd7c03a23721a3e8261e15aacf973 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Tue, 8 Jul 2014 14:39:23 -0400 Subject: [PATCH 18/50] Fixed some timer related issues. --- toxav/msi.c | 64 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 17 deletions(-) diff --git a/toxav/msi.c b/toxav/msi.c index 1219c64a..88f62ebd 100644 --- a/toxav/msi.c +++ b/toxav/msi.c @@ -538,7 +538,7 @@ GENERIC_SETTER_DEFINITION ( callid ) typedef struct _Timer { - void *(*func)(void *, int); + void *(*func)(void *); void *func_arg1; int func_arg2; uint64_t timeout; @@ -558,6 +558,10 @@ typedef struct _TimerHandler { } TimerHandler; +struct timer_function_args { + void *arg1; + int arg2; +}; /** * @brief Allocate timer in array @@ -568,8 +572,9 @@ typedef struct _TimerHandler { * @param timeout Timeout in ms * @return int */ -int timer_alloc ( TimerHandler *timers_container, void *(func)(void *, int), void *arg1, int arg2, unsigned timeout) +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); int i = 0; @@ -596,7 +601,8 @@ int timer_alloc ( TimerHandler *timers_container, void *(func)(void *, int), voi timer->func_arg1 = arg1; timer->func_arg2 = arg2; timer->timeout = timeout + current_time_monotonic(); /* In ms */ - timer->idx = i; + ++timer_id; + timer->idx = timer_id; /* reorder */ if (i) { @@ -612,15 +618,15 @@ int timer_alloc ( TimerHandler *timers_container, void *(func)(void *, int), voi pthread_mutex_unlock(&timers_container->mutex); LOGGER_DEBUG("Allocated timer index: %d timeout: %d, current size: %d", i, timeout, timers_container->size); - return i; + return timer->idx; } /** * @brief Remove timer from array * * @param timers_container handler - * @param idx index - * @param idx lock_mutex (does the mutex need to be locked) + * @param idx timer id + * @param lock_mutex (does the mutex need to be locked) * @return int */ int timer_release ( TimerHandler *timers_container, int idx , int lock_mutex) @@ -630,19 +636,28 @@ int timer_release ( TimerHandler *timers_container, int idx , int lock_mutex) Timer **timed_events = timers_container->timers; - if (!timed_events[idx]) { - LOGGER_WARNING("No event under index: %d", idx); + int i, res = -1; + + for (i = 0; i < timers_container->max_capacity; ++i) { + if (timed_events[i] && timed_events[i]->idx == idx) { + res = i; + break; + } + } + + if (res == -1) { + LOGGER_WARNING("No event with id: %d", idx); if (lock_mutex) pthread_mutex_unlock(&timers_container->mutex); return -1; } - free(timed_events[idx]); + free(timed_events[res]); - timed_events[idx] = NULL; + timed_events[res] = NULL; - int i = idx + 1; + i = res + 1; for (; i < timers_container->max_capacity && timed_events[i]; i ++) { timed_events[i - 1] = timed_events[i]; @@ -677,10 +692,21 @@ void *timer_poll( void *arg ) uint64_t time = current_time_monotonic(); if ( handler->timers[0] && handler->timers[0]->timeout < time ) { - handler->timers[0]->func(handler->timers[0]->func_arg1, handler->timers[0]->func_arg2); - LOGGER_DEBUG("Exectued timer assigned at: %d", handler->timers[0]->timeout); + pthread_t _tid; - timer_release(handler, 0, 0); + struct timer_function_args *args = malloc(sizeof(struct timer_function_args)); + args->arg1 = handler->timers[0]->func_arg1; + args->arg2 = handler->timers[0]->func_arg2; + + if ( 0 != pthread_create(&_tid, NULL, handler->timers[0]->func, args) || + 0 != pthread_detach(_tid) ) { + LOGGER_ERROR("Failed to execute timer at: %d!", handler->timers[0]->timeout); + free(args); + } else { + LOGGER_DEBUG("Exectued timer assigned at: %d", handler->timers[0]->timeout); + } + + timer_release(handler, handler->timers[0]->idx, 0); } } @@ -1140,14 +1166,15 @@ int terminate_call ( MSISession *session, MSICall *call ) * @param arg Control session * @return void* */ -void *handle_timeout ( void *arg1, int arg2 ) +void *handle_timeout ( void *arg ) { /* TODO: Cancel might not arrive there; set up * timers on these cancels and terminate call on * their timeout */ - int call_index = arg2; - MSISession *session = arg1; + struct timer_function_args *args = arg; + int call_index = args->arg2; + MSISession *session = args->arg1; MSICall *_call = session->calls[call_index]; if (_call) { @@ -1164,6 +1191,9 @@ void *handle_timeout ( void *arg1, int arg2 ) msi_cancel ( _call->session, _call->call_idx, _call->peers [0], "Request timed out" ); /*terminate_call(_call->session, _call);*/ } + + free(arg); + pthread_exit(NULL); } From 5e1ae35034330f4627ef8e83f0884914a8f880d2 Mon Sep 17 00:00:00 2001 From: Maxim Biro Date: Wed, 9 Jul 2014 14:00:16 -0400 Subject: [PATCH 19/50] Added a script to query DHT bootstrap node info --- other/fun/bootstrap_node_info.py | 98 ++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 other/fun/bootstrap_node_info.py diff --git a/other/fun/bootstrap_node_info.py b/other/fun/bootstrap_node_info.py new file mode 100644 index 00000000..17349334 --- /dev/null +++ b/other/fun/bootstrap_node_info.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python +""" +Copyright (c) 2014 by nurupo + +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] + " ") + 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) \ No newline at end of file From aeb12283f6f1b66af7c96a7443ed74982ba705f1 Mon Sep 17 00:00:00 2001 From: Sean Date: Wed, 9 Jul 2014 14:37:46 -0700 Subject: [PATCH 20/50] People are getting confused... --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cbe53af5..ff3a6bba 100644 --- a/README.md +++ b/README.md @@ -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.

-[**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)
- [Lossless UDP Protocol](https://wiki.tox.im/index.php/Lossless_UDP)
- [Crypto](https://wiki.tox.im/index.php/Crypto)
From 422ff3b77b3023c930161b992866ec54c419dbcc Mon Sep 17 00:00:00 2001 From: irungentoo Date: Wed, 9 Jul 2014 20:11:01 -0400 Subject: [PATCH 21/50] TCP should be a bit more solid. When a TCP ping request is recieved, try to send the response until success instead of just dropping it if sending the response fails on the first try. --- toxcore/TCP_client.c | 24 ++++++++++++++++++++---- toxcore/TCP_client.h | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 087188f7..82720ae8 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -197,6 +197,8 @@ 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); + /* return 1 on success. * return 0 if could not send packet. * return -1 on failure. @@ -209,6 +211,9 @@ 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) + return 0; + uint8_t packet[1 + length]; packet[0] = con_id + NUM_RESERVED_PORTS; memcpy(packet + 1, data, length); @@ -293,12 +298,21 @@ static int send_ping_request(TCP_Client_Connection *con, uint64_t ping_id) * 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) { + con->ping_response_id = 0; + } + + return ret; } /* return 1 on success. @@ -468,7 +482,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 +538,7 @@ 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); uint8_t packet[MAX_PACKET_SIZE]; int len; diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h index 2622b4f7..e6d232ed 100644 --- a/toxcore/TCP_client.h +++ b/toxcore/TCP_client.h @@ -57,6 +57,7 @@ typedef struct { uint64_t last_pinged; uint64_t ping_id; + uint64_t ping_response_id; void *net_crypto_pointer; uint32_t net_crypto_location; struct { From f89f189e30550dd5a0b6767d339dd2d6c3aeef7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20=C5=A0uppa?= Date: Thu, 10 Jul 2014 03:48:33 +0200 Subject: [PATCH 22/50] wintox has been renamned to uTox --- docs/TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/TODO b/docs/TODO index 966a1b5f..dea513b2 100644 --- a/docs/TODO +++ b/docs/TODO @@ -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 From e2d388b13799ddbe5ba2a81b442d6481cec5b611 Mon Sep 17 00:00:00 2001 From: notsecure Date: Thu, 10 Jul 2014 10:34:38 -0400 Subject: [PATCH 23/50] fix send rate going up when peer disconnects --- toxcore/net_crypto.c | 28 ++++++++++++++++++++++++++-- toxcore/net_crypto.h | 4 ++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index e0319f34..bc22a23e 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2250,6 +2250,24 @@ 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->last_queue_size + 100) { + double v1 = (double)(conn->packets_sent) / (double)(queue_size); + double v2 = (double)(conn->last_packets_sent) / (double)(conn->last_queue_size == 0 ? 1 : conn->last_queue_size); + if(v1 < v2) { + conn->packets_resent = conn->packets_sent; + conn->rate_increase = 0; + } + + conn->last_queue_size = queue_size; + conn->last_packets_sent = conn->packets_sent; + } else if(queue_size < conn->last_queue_size) { + conn->last_queue_size = queue_size; + conn->last_packets_sent = 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 +2318,22 @@ 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; - if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE || !conn->sending) { + if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE || !conn->sending || !conn->packets_sent) { conn->rate_increase = 0; 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 +2364,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 +2444,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; } diff --git a/toxcore/net_crypto.h b/toxcore/net_crypto.h index 4fed0000..2bc9a716 100644 --- a/toxcore/net_crypto.h +++ b/toxcore/net_crypto.h @@ -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. */ From 1d6c3934736c3694a7c9f694d818252e4159cde3 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Thu, 10 Jul 2014 18:15:55 -0400 Subject: [PATCH 24/50] Made TCP a bit more solid. TCP ping requests in TCP_client should have a higher success rate. --- toxcore/TCP_client.c | 33 +++++++++++++++++++-------------- toxcore/TCP_client.h | 2 ++ 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 82720ae8..6ead44a5 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -198,6 +198,7 @@ void routing_status_handler(TCP_Client_Connection *con, int (*status_callback)(v } 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. @@ -211,7 +212,7 @@ 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) + if (send_ping_response(con) == 0 || send_ping_request(con) == 0) return 0; uint8_t packet[1 + length]; @@ -286,12 +287,21 @@ static int send_disconnect_notification(TCP_Client_Connection *con, uint8_t id) * 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) { + con->ping_request_id = 0; + } + + return ret; } /* return 1 on success. @@ -539,6 +549,8 @@ 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; @@ -548,16 +560,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)) { diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h index e6d232ed..f57f79e6 100644 --- a/toxcore/TCP_client.h +++ b/toxcore/TCP_client.h @@ -58,6 +58,8 @@ typedef struct { uint64_t ping_id; uint64_t ping_response_id; + uint64_t ping_request_id; + void *net_crypto_pointer; uint32_t net_crypto_location; struct { From 271f03a7170d01986c167844536a4340888815c4 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Thu, 10 Jul 2014 18:20:07 -0400 Subject: [PATCH 25/50] Call now gets terminated when other person times out. --- toxav/msi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/toxav/msi.c b/toxav/msi.c index 88f62ebd..26b37292 100644 --- a/toxav/msi.c +++ b/toxav/msi.c @@ -959,6 +959,7 @@ void handle_remote_connection_change(Messenger *messenger, int friend_num, uint8 for ( ; i < session->calls[j]->peer_count; i ++ ) if ( session->calls[j]->peers[i] == friend_num ) { invoke_callback(j, MSI_OnPeerTimeout); + terminate_call(session, session->calls[j]); LOGGER_DEBUG("Remote: %d timed out!", friend_num); return; /* TODO: On group calls change behaviour */ } From a5d2775c2570121c34a13d248662adb5c4770f9b Mon Sep 17 00:00:00 2001 From: notsecure Date: Fri, 11 Jul 2014 10:23:40 -0400 Subject: [PATCH 26/50] . --- toxcore/net_crypto.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index bc22a23e..7c0dd77b 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2252,19 +2252,9 @@ static void send_crypto_packets(Net_Crypto *c) /* 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->last_queue_size + 100) { - double v1 = (double)(conn->packets_sent) / (double)(queue_size); - double v2 = (double)(conn->last_packets_sent) / (double)(conn->last_queue_size == 0 ? 1 : conn->last_queue_size); - if(v1 < v2) { - conn->packets_resent = conn->packets_sent; - conn->rate_increase = 0; - } - - conn->last_queue_size = queue_size; - conn->last_packets_sent = conn->packets_sent; - } else if(queue_size < conn->last_queue_size) { - conn->last_queue_size = queue_size; - conn->last_packets_sent = conn->packets_sent; + if(queue_size > conn->packet_send_rate && queue_size > conn->last_queue_size) { + conn->rate_increase = 0; + conn->packets_resent = conn->packets_sent; } @@ -2326,6 +2316,7 @@ static void send_crypto_packets(Net_Crypto *c) 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 || !conn->packets_sent) { conn->rate_increase = 0; From 21e797ac90a06232aef03e47faecc048910ba1e3 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Fri, 11 Jul 2014 13:30:10 -0400 Subject: [PATCH 27/50] Fixed some small TCP issues. --- toxcore/TCP_client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 6ead44a5..bc1b7ff4 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -451,7 +451,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; @@ -475,7 +475,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; From 72858076f54da1b94739a79d3be9ee6434d785ce Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 12 Jul 2014 23:24:47 -0400 Subject: [PATCH 28/50] Set a deadline in the vpx video decoder to try to solve issues on slow hardware. --- toxav/toxav.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/toxav/toxav.c b/toxav/toxav.c index a301e007..aa903ff7 100644 --- a/toxav/toxav.c +++ b/toxav/toxav.c @@ -37,8 +37,9 @@ #include #include -/* 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*/ @@ -794,7 +795,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; From 4fa115e6d09057219e317dd49bb7b8a3bd2b45f7 Mon Sep 17 00:00:00 2001 From: Jin^eLD Date: Sun, 13 Jul 2014 20:01:06 +0300 Subject: [PATCH 29/50] Fixed documentation comment errors --- toxcore/tox.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/toxcore/tox.h b/toxcore/tox.h index d931b9be..b44648fc 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -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); From 8fd457c67f76efbdc0f72e8dc1eb514323d81101 Mon Sep 17 00:00:00 2001 From: Jin^eLD Date: Sun, 13 Jul 2014 23:20:31 +0300 Subject: [PATCH 30/50] Fix win32 mingw native build toxdns was not linking because of references to functions in crypto_core --- toxdns/Makefile.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/toxdns/Makefile.inc b/toxdns/Makefile.inc index 1e66ab3f..689a58a5 100644 --- a/toxdns/Makefile.inc +++ b/toxdns/Makefile.inc @@ -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 From 0244bd596deaba90bcf9282e1709ea5f25b328ca Mon Sep 17 00:00:00 2001 From: irungentoo Date: Mon, 14 Jul 2014 12:21:13 -0400 Subject: [PATCH 31/50] Attempted fix of file transfer issue. Instead of dropping the rate to minimum just half it until it drops to the minimum. --- toxcore/net_crypto.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 7c0dd77b..bb1bbe05 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -2318,8 +2318,12 @@ static void send_crypto_packets(Net_Crypto *c) conn->packets_resent = 0; conn->last_queue_size = queue_size; - if (conn->packet_send_rate < CRYPTO_PACKET_MIN_RATE || !conn->sending || !conn->packets_sent) { + 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; } From 4da8664a1521f2feeafbe8c036380c670cbc6d32 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Mon, 14 Jul 2014 16:23:19 -0400 Subject: [PATCH 32/50] Packets can now be sent from the connection status callback. --- toxcore/net_crypto.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index bb1bbe05..10921abb 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -1149,11 +1149,11 @@ static int handle_data_packet_helper(const Net_Crypto *c, int crypt_connection_i } 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; + + if (conn->connection_status_callback) + conn->connection_status_callback(conn->connection_status_callback_object, conn->connection_status_callback_id, 1); } return 0; @@ -2252,7 +2252,8 @@ static void send_crypto_packets(Net_Crypto *c) /* 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) { + + if (queue_size > conn->packet_send_rate && queue_size > conn->last_queue_size) { conn->rate_increase = 0; conn->packets_resent = conn->packets_sent; } From 2ea634ece28b11ef204b3669a42dde30c5e24ffe Mon Sep 17 00:00:00 2001 From: irungentoo Date: Mon, 14 Jul 2014 16:37:43 -0400 Subject: [PATCH 33/50] Set packets_left to default non zero values when creating connection. --- toxcore/net_crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 10921abb..3751d0e2 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -1485,6 +1485,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 +1518,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; } From 32ed095d7271a311a89d1430610e3adb4568ce2c Mon Sep 17 00:00:00 2001 From: irungentoo Date: Mon, 14 Jul 2014 18:20:17 -0400 Subject: [PATCH 34/50] Change connection status before handling data packets. --- toxcore/net_crypto.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 3751d0e2..c44d09c4 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -1106,6 +1106,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 +1156,6 @@ 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); - } - return 0; } From 59821d6a5ef5b298a66feaaca337e71e9cecab61 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Mon, 14 Jul 2014 18:36:26 -0400 Subject: [PATCH 35/50] Fixed file sending documentation. --- toxcore/tox.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/toxcore/tox.h b/toxcore/tox.h index b44648fc..14426f31 100644 --- a/toxcore/tox.h +++ b/toxcore/tox.h @@ -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... */ From 078d60ab929ca7ba50ba9e7de5745456c6114352 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Tue, 15 Jul 2014 12:35:57 -0400 Subject: [PATCH 36/50] Fixed bug with TCP. Don't increment nonce if packet was discarded instead of being sent. --- toxcore/TCP_client.c | 10 +++++----- toxcore/TCP_server.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index bc1b7ff4..2a2289b2 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -155,16 +155,16 @@ 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); - len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL); - if ((unsigned int)len == sizeof(packet)) - return 1; - if (len <= 0) return 0; + increment_nonce(con->sent_nonce); + + if ((unsigned int)len == sizeof(packet)) + return 1; + memcpy(con->last_packet, packet, length); con->last_packet_length = sizeof(packet); con->last_packet_sent = len; diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index 7487ad4f..6c0133dd 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -335,16 +335,16 @@ 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); - len = send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL); - if ((unsigned int)len == sizeof(packet)) - return 1; - if (len <= 0) return 0; + increment_nonce(con->sent_nonce); + + if ((unsigned int)len == sizeof(packet)) + return 1; + memcpy(con->last_packet, packet, length); con->last_packet_length = sizeof(packet); con->last_packet_sent = len; From ae7a11cae9e220ce0a66bc48977104495759a01a Mon Sep 17 00:00:00 2001 From: irungentoo Date: Tue, 15 Jul 2014 13:39:32 -0400 Subject: [PATCH 37/50] Fixed TCP bug. Packet was being copied with a wrong, smaller length. --- toxcore/TCP_client.c | 2 +- toxcore/TCP_server.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 2a2289b2..dbcae11b 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -165,7 +165,7 @@ static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const if ((unsigned int)len == sizeof(packet)) return 1; - memcpy(con->last_packet, packet, length); + memcpy(con->last_packet, packet, sizeof(packet)); con->last_packet_length = sizeof(packet); con->last_packet_sent = len; return 1; diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index 6c0133dd..e7ef0d3a 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -345,7 +345,7 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const if ((unsigned int)len == sizeof(packet)) return 1; - memcpy(con->last_packet, packet, length); + memcpy(con->last_packet, packet, sizeof(packet)); con->last_packet_length = sizeof(packet); con->last_packet_sent = len; return 1; From 22d28ddf36563e2d0018fc20cafdfe61278dd67f Mon Sep 17 00:00:00 2001 From: notsecure Date: Tue, 15 Jul 2014 17:40:21 -0400 Subject: [PATCH 38/50] added priority packet system for TCP server --- toxcore/TCP_server.c | 109 +++++++++++++++++++++++++++++++++++++------ toxcore/TCP_server.h | 10 ++++ 2 files changed, 104 insertions(+), 15 deletions(-) diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index e7ef0d3a..8b7d5fdd 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -306,25 +306,94 @@ 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_priority(TCP_Secure_Connection *con) +{ + 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, int sent) +{ + if(sent == size) { + return 1; + } + + if(sent <= 0) { + sent = 0; + } + + 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_priority(con) == -1) { + if (priority) { + sendpriority = 0; + } else { + return 0; + } + } uint8_t packet[sizeof(uint16_t) + length + crypto_box_MACBYTES]; @@ -332,6 +401,13 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const memcpy(packet, &c_length, sizeof(uint16_t)); int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); + if (priority) { + return add_priority(con, packet, sizeof(packet), sendpriority ? send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL) : 0); + } + + if (send_pending_data(con) == -1) + return 0; + if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) return -1; @@ -459,7 +535,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 +545,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 +555,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 +655,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 +713,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 +758,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 +828,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 +1134,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(); @@ -1076,7 +1152,10 @@ static void do_TCP_confirmed(TCP_Server *TCP_server) continue; } - send_pending_data(conn); + /* try sending queued priority packets first */ + if(send_pending_data_priority(conn) == 0) { + send_pending_data(conn); + } #ifndef TCP_SERVER_USE_EPOLL diff --git a/toxcore/TCP_server.h b/toxcore/TCP_server.h index def0a978..81507acb 100644 --- a/toxcore/TCP_server.h +++ b/toxcore/TCP_server.h @@ -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; From 96249e8b020c76e9f80da6538ea19699612479dc Mon Sep 17 00:00:00 2001 From: notsecure Date: Tue, 15 Jul 2014 18:22:04 -0400 Subject: [PATCH 39/50] fixed some issues --- toxcore/TCP_server.c | 48 +++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index 8b7d5fdd..15c2b45d 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -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; @@ -314,8 +314,13 @@ static int send_pending_data(TCP_Secure_Connection *con) /* return 0 if pending data was sent completely * return -1 if it wasn't */ -static int send_pending_data_priority(TCP_Secure_Connection *con) +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) { @@ -346,16 +351,8 @@ static int send_pending_data_priority(TCP_Secure_Connection *con) /* 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, int sent) +static _Bool add_priority(TCP_Secure_Connection *con, const uint8_t *packet, uint16_t size, uint16_t sent) { - if(sent == size) { - return 1; - } - - if(sent <= 0) { - sent = 0; - } - TCP_Priority_List *p = con->priority_queue_end, *new; new = malloc(sizeof(TCP_Priority_List) + size); if(!new) { @@ -387,7 +384,7 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const return -1; _Bool sendpriority = 1; - if (send_pending_data_priority(con) == -1) { + if (send_pending_data(con) == -1) { if (priority) { sendpriority = 0; } else { @@ -401,16 +398,24 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const memcpy(packet, &c_length, sizeof(uint16_t)); int len = encrypt_data_symmetric(con->shared_key, con->sent_nonce, data, length, packet + sizeof(uint16_t)); - if (priority) { - return add_priority(con, packet, sizeof(packet), sendpriority ? send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL) : 0); - } - - if (send_pending_data(con) == -1) - return 0; - if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) return -1; + if (priority) { + len = sendpriority ? send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL) : 0; + if(len <= 0) { + len = 0; + } else { + 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 (len <= 0) @@ -1152,10 +1157,7 @@ static void do_TCP_confirmed(TCP_Server *TCP_server) continue; } - /* try sending queued priority packets first */ - if(send_pending_data_priority(conn) == 0) { - send_pending_data(conn); - } + send_pending_data(conn); #ifndef TCP_SERVER_USE_EPOLL From e04fff3eac1c1fe1bb663edd8d0b45a9798ace83 Mon Sep 17 00:00:00 2001 From: notsecure Date: Wed, 16 Jul 2014 08:33:24 -0400 Subject: [PATCH 40/50] applied priority queue changes to the TCP client too --- toxcore/TCP_client.c | 109 +++++++++++++++++++++++++++++++++++++------ toxcore/TCP_client.h | 2 + 2 files changed, 97 insertions(+), 14 deletions(-) diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index dbcae11b..4aed0ff5 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -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,90 @@ 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,6 +221,21 @@ static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const if ((unsigned int)len != (sizeof(packet) - sizeof(uint16_t))) return -1; + if (priority) { + len = sendpriority ? send(con->sock, packet, sizeof(packet), MSG_NOSIGNAL) : 0; + if(len <= 0) { + len = 0; + } else { + 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 (len <= 0) @@ -180,7 +261,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, @@ -218,7 +299,7 @@ int send_data(TCP_Client_Connection *con, uint8_t con_id, const uint8_t *data, u 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. @@ -234,7 +315,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); } @@ -280,7 +361,7 @@ 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. @@ -297,7 +378,7 @@ static int send_ping_request(TCP_Client_Connection *con) memcpy(packet + 1, &con->ping_request_id, sizeof(uint64_t)); int ret; - if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet))) == 1) { + if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1)) == 1) { con->ping_request_id = 0; } @@ -318,7 +399,7 @@ static int send_ping_response(TCP_Client_Connection *con) memcpy(packet + 1, &con->ping_response_id, sizeof(uint64_t)); int ret; - if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet))) == 1) { + if ((ret = write_packet_TCP_secure_connection(con, packet, sizeof(packet), 1)) == 1) { con->ping_response_id = 0; } @@ -348,7 +429,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, diff --git a/toxcore/TCP_client.h b/toxcore/TCP_client.h index f57f79e6..9998d20c 100644 --- a/toxcore/TCP_client.h +++ b/toxcore/TCP_client.h @@ -52,6 +52,8 @@ 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; From 13b23b1a0157785e18d7ef551a1a5a0e0006ee64 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Wed, 16 Jul 2014 18:29:00 -0400 Subject: [PATCH 41/50] fix memory leak --- toxcore/group_chats.c | 1 + 1 file changed, 1 insertion(+) diff --git a/toxcore/group_chats.c b/toxcore/group_chats.c index 53ef69d3..77fa6acd 100644 --- a/toxcore/group_chats.c +++ b/toxcore/group_chats.c @@ -820,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); } From bcfb1261ac4ab5f6470924f473c8c18bc5f98f01 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Wed, 16 Jul 2014 20:39:58 -0400 Subject: [PATCH 42/50] Fixed possible bug with TCP nonce not getting incremented. --- toxcore/TCP_client.c | 4 ++-- toxcore/TCP_server.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/toxcore/TCP_client.c b/toxcore/TCP_client.c index 02d4e7dc..45220538 100644 --- a/toxcore/TCP_client.c +++ b/toxcore/TCP_client.c @@ -231,10 +231,10 @@ static int write_packet_TCP_secure_connection(TCP_Client_Connection *con, const if (len <= 0) { len = 0; - } else { - increment_nonce(con->sent_nonce); } + increment_nonce(con->sent_nonce); + if (len == sizeof(packet)) { return 1; } diff --git a/toxcore/TCP_server.c b/toxcore/TCP_server.c index f3cdd287..47e2ff27 100644 --- a/toxcore/TCP_server.c +++ b/toxcore/TCP_server.c @@ -411,10 +411,10 @@ static int write_packet_TCP_secure_connection(TCP_Secure_Connection *con, const if (len <= 0) { len = 0; - } else { - increment_nonce(con->sent_nonce); } + increment_nonce(con->sent_nonce); + if (len == sizeof(packet)) { return 1; } From 733c5196011a79ec02851c9d268df4f4181850f3 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Thu, 17 Jul 2014 20:44:49 -0400 Subject: [PATCH 43/50] Build system now automatically enables epoll support in TCP server when supported. --- configure.ac | 19 ++++++++ m4/ax_have_epoll.m4 | 104 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 m4/ax_have_epoll.m4 diff --git a/configure.ac b/configure.ac index 0dd88da4..174ecbe0 100644 --- a/configure.ac +++ b/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= diff --git a/m4/ax_have_epoll.m4 b/m4/ax_have_epoll.m4 new file mode 100644 index 00000000..07ceb49f --- /dev/null +++ b/m4/ax_have_epoll.m4 @@ -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 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 +# +# 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 +#ifdef HAVE_LINUX_VERSION_H +# include +# 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 +# if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +# error linux kernel version is too old to have epoll_pwait +# endif +#endif +#include +#include +], [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 From 9c84b5401cdfb621b2e77751ad869b7fea786885 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Fri, 18 Jul 2014 21:34:22 -0400 Subject: [PATCH 44/50] Spread packets over many TCP relays instead of just using the first one. --- toxcore/net_crypto.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index c44d09c4..18dd3b05 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -426,19 +426,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; } } From f0a172f1989c9626d3986099f086ea3ff202563b Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 19 Jul 2014 22:08:05 -0400 Subject: [PATCH 45/50] Set some functions as static, fixed warning. --- toxav/msi.c | 70 +++++++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/toxav/msi.c b/toxav/msi.c index 26b37292..dca5fe1e 100644 --- a/toxav/msi.c +++ b/toxav/msi.c @@ -207,7 +207,7 @@ static inline__ const uint8_t *stringify_response ( MSIResponse response ) * @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 ON_HEADER(iterator, size_con, header, descriptor, type_size_const) \ @@ -308,7 +308,7 @@ var.size = t_size; } * @param msg The message. * @return void */ -void free_message ( MSIMessage *msg ) +static void free_message ( MSIMessage *msg ) { if ( msg == NULL ) { LOGGER_WARNING("Tried to free empty message"); @@ -335,7 +335,7 @@ void free_message ( MSIMessage *msg ) * @return MSIMessage* Created message. * @retval NULL Error occurred. */ -MSIMessage *msi_new_message ( uint8_t type, const uint8_t *type_id ) +static MSIMessage *msi_new_message ( uint8_t type, const uint8_t *type_id ) { MSIMessage *_retu = calloc ( sizeof ( MSIMessage ), 1 ); @@ -368,7 +368,7 @@ MSIMessage *msi_new_message ( uint8_t type, const uint8_t *type_id ) * @return MSIMessage* Parsed message. * @retval NULL Error occurred. */ -MSIMessage *parse_message ( const uint8_t *data, uint16_t length ) +static MSIMessage *parse_message ( const uint8_t *data, uint16_t length ) { if ( data == NULL ) { LOGGER_WARNING("Tried to parse empty message!"); @@ -411,7 +411,7 @@ MSIMessage *parse_message ( const uint8_t *data, uint16_t length ) * @param length Pointer to container length. * @return uint8_t* Iterated container. */ -uint8_t *append_header_to_string ( +static uint8_t *append_header_to_string ( uint8_t *dest, const uint8_t *header_field, const uint8_t *header_value, @@ -490,7 +490,7 @@ uint8_t *append_header_to_string ( * @param dest Destination. * @return uint16_t It's final size. */ -uint16_t message_to_send ( MSIMessage *msg, uint8_t *dest ) +static uint16_t message_to_send ( MSIMessage *msg, uint8_t *dest ) { #define CLEAN_ASSIGN(added, var, field, header)\ if ( header.header_value ) { var = append_header_to_string(var, (const uint8_t*)field, header.header_value, header.size, &added); } @@ -572,7 +572,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); @@ -629,7 +629,7 @@ int timer_alloc ( TimerHandler *timers_container, void *(func)(void *), void *ar * @param lock_mutex (does the mutex need to be locked) * @return int */ -int timer_release ( TimerHandler *timers_container, int idx , int lock_mutex) +static int timer_release ( TimerHandler *timers_container, int idx , int lock_mutex) { if (lock_mutex) pthread_mutex_lock(&timers_container->mutex); @@ -679,7 +679,7 @@ int timer_release ( TimerHandler *timers_container, int idx , int lock_mutex) * @param arg ... * @return void* */ -void *timer_poll( void *arg ) +static void *timer_poll( void *arg ) { TimerHandler *handler = arg; @@ -726,7 +726,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)); @@ -768,7 +768,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); @@ -793,7 +793,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!"); @@ -881,7 +881,7 @@ static inline__ const uint8_t *stringify_error_code ( 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, CALL_ID_LEN ); @@ -911,7 +911,7 @@ int send_message ( MSISession *session, MSICall *call, MSIMessage *msg, uint32_t * @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, CALL_ID_LEN) < 0); } @@ -925,7 +925,7 @@ int call_id_bigger( const uint8_t *first, const uint8_t *second) * @param peer_id The peer. * @return void */ -void flush_peer_type ( MSICall *call, MSIMessage *msg, int peer_id ) +static void flush_peer_type ( MSICall *call, MSIMessage *msg, int peer_id ) { if ( msg->calltype.header_value ) { uint8_t hdrval [MSI_MAXMSG_SIZE]; /* Make sure no overflow */ @@ -942,7 +942,9 @@ void flush_peer_type ( MSICall *call, MSIMessage *msg, int peer_id ) } else {} /* Error */ } -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; @@ -972,7 +974,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; @@ -1000,7 +1002,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"); @@ -1034,7 +1036,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); @@ -1060,7 +1062,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) { @@ -1122,7 +1124,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!"); @@ -1167,7 +1169,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 @@ -1199,7 +1201,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: %s", session, call ? (char *)call->id : "making new"); @@ -1273,7 +1275,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"); @@ -1293,7 +1296,8 @@ int handle_recv_start ( MSISession *session, MSICall *call, MSIMessage *msg ) invoke_callback(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"); @@ -1316,7 +1320,8 @@ int handle_recv_reject ( MSISession *session, MSICall *call, MSIMessage *msg ) terminate_call(session, call); 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"); @@ -1335,7 +1340,8 @@ int handle_recv_cancel ( MSISession *session, MSICall *call, MSIMessage *msg ) terminate_call ( session, call ); 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"); @@ -1359,7 +1365,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"); @@ -1384,7 +1390,7 @@ int handle_recv_ringing ( MSISession *session, MSICall *call, MSIMessage *msg ) invoke_callback(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 'start' on no call"); @@ -1410,7 +1416,7 @@ int handle_recv_starting ( MSISession *session, MSICall *call, MSIMessage *msg ) invoke_callback(call->call_idx, MSI_OnStarting); 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"); @@ -1433,7 +1439,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 ) { pthread_mutex_lock(&session->mutex); @@ -1494,7 +1500,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 */ From 8195ade7092e6261b6554ca9657eeded3c220c8d Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sat, 19 Jul 2014 22:09:30 -0400 Subject: [PATCH 46/50] Removed useless function. --- toxcore/net_crypto.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/toxcore/net_crypto.c b/toxcore/net_crypto.c index 18dd3b05..ac2359ee 100644 --- a/toxcore/net_crypto.c +++ b/toxcore/net_crypto.c @@ -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) From 4e85be6a68e83023a200088167336ead0f8f860d Mon Sep 17 00:00:00 2001 From: stal Date: Sat, 19 Jul 2014 19:18:15 -0700 Subject: [PATCH 47/50] declare calculate_sum_sq static inline --- toxav/codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxav/codec.c b/toxav/codec.c index ae24a976..4a12ffb2 100644 --- a/toxav/codec.c +++ b/toxav/codec.c @@ -383,7 +383,7 @@ void codec_terminate_session ( CodecState *cs ) free(cs); } -inline float calculate_sum_sq (int16_t *n, uint16_t k) +static inline float calculate_sum_sq (int16_t *n, uint16_t k) { float result = 0; uint16_t i = 0; From cc1466ec09e12c7aeb39690a32affbd4cf3b897b Mon Sep 17 00:00:00 2001 From: stal Date: Sat, 19 Jul 2014 19:29:56 -0700 Subject: [PATCH 48/50] remove this too --- toxav/codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/toxav/codec.c b/toxav/codec.c index 4a12ffb2..b7ca2784 100644 --- a/toxav/codec.c +++ b/toxav/codec.c @@ -383,7 +383,7 @@ void codec_terminate_session ( CodecState *cs ) free(cs); } -static 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; From 97ad1e62b676682bb4f1950023460e326b216841 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sun, 20 Jul 2014 20:08:00 -0400 Subject: [PATCH 49/50] Added addr_parse_ip() to network.h header. Removed useless semicolons. --- toxcore/network.c | 26 ++++++++++++-------------- toxcore/network.h | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/toxcore/network.c b/toxcore/network.c index 0009a558..373fef9e 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -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; -}; +} diff --git a/toxcore/network.h b/toxcore/network.h index 359d26c8..b902a487 100644 --- a/toxcore/network.h +++ b/toxcore/network.h @@ -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 From b63e4ad88fb93820fb740372f36d74c65b8b7b81 Mon Sep 17 00:00:00 2001 From: irungentoo Date: Sun, 20 Jul 2014 20:50:53 -0400 Subject: [PATCH 50/50] LAN discovery should now work on windows machines with multiple ethernet devices. Added some code to get real adapter broadcast addresses on windows. --- configure.ac | 2 +- toxcore/LAN_discovery.c | 75 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 174ecbe0..d1c54c71 100644 --- a/configure.ac +++ b/configure.ac @@ -662,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) ], [ diff --git a/toxcore/LAN_discovery.c b/toxcore/LAN_discovery.c index e1b8534c..420c490d 100644 --- a/toxcore/LAN_discovery.c +++ b/toxcore/LAN_discovery.c @@ -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 + +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;