merge 1.10.12

This commit is contained in:
Preston Baxter 2024-02-06 23:39:00 -06:00
commit 4df5fc09be
47 changed files with 5353 additions and 7854 deletions

View File

@ -67,8 +67,8 @@ This is the place to get answers faster and chat with other users in real time.
Slack Community:
* https://signalwire.community/
Mailing list:
Mailing list (ARCHIVED):
* http://lists.freeswitch.org/mailman/listinfo/freeswitch-users
* http://lists.freeswitch.org/pipermail/freeswitch-users/
**Thank you for using FreeSWITCH!**

View File

@ -1 +1 @@
1.10.10-release
1.10.12-dev

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,10 @@
# Must change all of the below together
# For a release, set revision for that tagged release as well and uncomment
AC_INIT([freeswitch], [1.10.10-release], bugs@freeswitch.org)
AC_INIT([freeswitch], [1.10.12-dev], bugs@freeswitch.org)
AC_SUBST(SWITCH_VERSION_MAJOR, [1])
AC_SUBST(SWITCH_VERSION_MINOR, [10])
AC_SUBST(SWITCH_VERSION_MICRO, [10-release])
AC_SUBST(SWITCH_VERSION_MICRO, [12-dev])
AC_SUBST(SWITCH_VERSION_REVISION, [])
AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, [])
@ -29,8 +29,8 @@ AC_SUBST(switch_srcdir)
AC_SUBST(switch_builddir)
#
# --enable-64 has been moved up higher prior to AC_PROG_CC so that we can tuck in the -m64 flag
# so devs on with Solaris wanting to build 64bit can not bother with adding any additional
# --enable-64 has been moved up higher prior to AC_PROG_CC so that we can tuck in the -m64 flag
# so devs on with Solaris wanting to build 64bit can not bother with adding any additional
# flags on the ./configure line. User friendly.
#
@ -540,7 +540,7 @@ if test "${enable_debug}" = "yes"; then
CFLAGS=
AX_CFLAGS_WARN_ALL_ANSI
SWITCH_ANSI_CFLAGS=$CFLAGS
CFLAGS="$saved_CFLAGS"
CFLAGS="$saved_CFLAGS"
if test "x${ax_cv_c_compiler_vendor}" = "xgnu" ; then
if test "$ac_cv_gcc_supports_w_no_unused_result" = yes; then
@ -716,7 +716,7 @@ PKG_CHECK_MODULES([SPANDSP], [spandsp >= 3.0],[
AC_MSG_ERROR([no usable spandsp; please install spandsp3 devel package or equivalent])
])
PKG_CHECK_MODULES([SOFIA_SIP], [sofia-sip-ua >= 1.13.15],[
PKG_CHECK_MODULES([SOFIA_SIP], [sofia-sip-ua >= 1.13.17],[
AM_CONDITIONAL([HAVE_SOFIA_SIP],[true])],[
AC_MSG_ERROR([no usable sofia-sip; please install sofia-sip-ua devel package or equivalent])
])
@ -1029,7 +1029,7 @@ va_list_is_array=no
AC_MSG_CHECKING(whether va_list is an array)
AC_TRY_COMPILE([
#include <stdarg.h>
], [va_list list1, list2; list1 = list2;], ,
], [va_list list1, list2; list1 = list2;], ,
va_list_is_array=yes)
AC_MSG_RESULT($va_list_is_array)
if test x"$va_list_is_array" = xyes; then
@ -1079,7 +1079,7 @@ if test "x${ax_cv_c_compiler_vendor}" = "xclang" ; then
fi
# Tested and fixed lot of modules, but some are untested. Will be added back when the core team decide it ready
# Untested modules : mod_osp mod_soundtouch mod_sangoma_codec mod_opal mod_h323 mod_khomp
# Untested modules : mod_osp mod_soundtouch mod_sangoma_codec mod_opal mod_h323 mod_khomp
# mod_cepstral mod_erlang_event mod_snmp mod_perl mod_java mod_managed
#
#saved_CFLAGS="$CFLAGS"
@ -1191,8 +1191,8 @@ else
fi
# Basically, we have tried to figure out the correct format strings
# for SWITCH types which vary between platforms, but we don't always get
# it right. If you find that we don't get it right for your platform,
# for SWITCH types which vary between platforms, but we don't always get
# it right. If you find that we don't get it right for your platform,
# you can override our decision below.
# NOTE: borrowed much of this logic from apr.
case $host in
@ -1229,9 +1229,9 @@ AC_SUBST(long_value)
AC_SUBST(int64_value)
AC_SUBST(size_t_value)
AC_SUBST(ssize_t_value)
AC_SUBST(int64_t_fmt)
AC_SUBST(uint64_t_fmt)
AC_SUBST(ssize_t_fmt)
AC_SUBST(int64_t_fmt)
AC_SUBST(uint64_t_fmt)
AC_SUBST(ssize_t_fmt)
AC_SUBST(size_t_fmt)
case $host in
@ -1480,7 +1480,7 @@ PKG_CHECK_MODULES([SOUNDTOUCH], [soundtouch >= 1.7.0],[
flite="true"
PKG_CHECK_MODULES([FLITE], [flite >= 2],[],[
AC_CHECK_LIB([flite], [flite_init],[
AC_CHECK_HEADERS([flite/flite.h],[
AC_CHECK_HEADERS([flite/flite.h],[
FLITE_LIBS="-lflite -lflite_cmu_grapheme_lang -lflite_cmu_grapheme_lex -lflite_cmu_indic_lang -lflite_cmu_indic_lex -lflite_cmulex -lflite_cmu_time_awb -lflite_cmu_us_awb -lflite_cmu_us_kal16 -lflite_cmu_us_kal -lflite_cmu_us_rms -lflite_cmu_us_slt -lflite_usenglish"
FLITE_CFLAGS=""
], [
@ -1588,7 +1588,7 @@ PKG_CHECK_MODULES([HIREDIS], [hiredis >= 0.10.0],[
AM_CONDITIONAL([HAVE_HIREDIS],[true])],[
AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_HIREDIS],[false])])
AC_ARG_ENABLE(core-libedit-support,
AC_ARG_ENABLE(core-libedit-support,
[AS_HELP_STRING([--disable-core-libedit-support], [Compile without libedit Support])])
AS_IF([test "x$enable_core_libedit_support" != "xno"],[
@ -1670,7 +1670,7 @@ else
fi
AX_CHECK_JAVA
AM_CONDITIONAL([HAVE_ODBC],[test "x$enable_core_odbc_support" != "xno"])
AM_CONDITIONAL([HAVE_MYSQL],[test "$found_mysql" = "yes"])

4
debian/bootstrap.sh vendored
View File

@ -335,7 +335,7 @@ Build-Depends:
uuid-dev, libexpat1-dev, libgdbm-dev, libdb-dev,
# used by many modules
libcurl4-openssl-dev | libcurl4-gnutls-dev | libcurl-dev,
bison, zlib1g-dev, libsofia-sip-ua-dev (>= 1.13.15),
bison, zlib1g-dev, libsofia-sip-ua-dev (>= 1.13.17),
libspandsp3-dev,
# used to format the private freeswitch apt-repo key properly
gnupg,
@ -374,7 +374,7 @@ Description: Cross-Platform Scalable Multi-Protocol Soft Switch
Package: libfreeswitch1
Architecture: amd64 armhf
Depends: \${shlibs:Depends}, \${misc:Depends}, libsofia-sip-ua0 (>= 1.13.15)
Depends: \${shlibs:Depends}, \${misc:Depends}, libsofia-sip-ua0 (>= 1.13.17)
Recommends:
Suggests: libfreeswitch1-dbg
Conflicts: freeswitch-all (<= 1.6.7)

View File

@ -2,7 +2,7 @@
These are the official Docker files for master branch and the current release packages.
## Volumes
These containers are setup so that you can mount your freeswitch configuration form a host or data volume container.
These containers are set up so that you can mount your freeswitch configuration from a host or data volume container.
To mount freeswitch Configuration
```
@ -16,17 +16,19 @@ To mount tmp directory for storing recordings, etc
The container also has a healthcheck where it does a fs_cli status check to make sure the freeswitch service is still running.
# Ports
## Ports
The container exposes the following ports:
The container should be run with host networking using `docker run --network host ...`.
- 5060/tcp 5060/udp 5080/tcp 5080/udp as SIP Signaling ports.
- 5066/tcp 7443/tcp as WebSocket Signaling ports.
- 8021/tcp as Event Socket port.
- 64535-65535/udp as media ports.
- 16384-32768/udp
If you prefer to (or for some reason must) publish individual ports via `--publish/-p`, refer to this [issue](https://github.com/moby/moby/issues/11185) and this [potential workaround](https://hub.docker.com/r/bettervoice/freeswitch-container/) regarding using docker with large port ranges.
The following ports will be used, depending upon your specific configuration:
- 5060/tcp, 5060/udp, 5080/tcp, 5080/udp - SIP signaling
- 5061/tcp, 5081/tcp - SIPS signaling
- 5066/tcp, 7443/tcp - WebSocket signaling
- 8021/tcp - the Event Socket
- 16384-32768/udp, 64535-65535/udp - media
If you wish to help improve these please submit a pull request at:

View File

@ -1,56 +1,61 @@
# vim:set ft=dockerfile:
ARG DEBIAN_VERSION=buster
ARG DEBIAN_VERSION=bookworm
FROM debian:${DEBIAN_VERSION}
# ARGs are cleared after every FROM
# see: https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact
ARG DEBIAN_VERSION
ARG TOKEN
# By default, install the full set of FreeSWITCH packages. Specify an alternative with:
# --build-arg="FS_META_PACKAGE=freeswitch-meta-vanilla"
# alternatives include:
# freeswitch-meta-bare
# freeswitch-meta-vanilla
# freeswitch-meta-sorbet
# freeswitch-meta-all-dbg
ARG FS_META_PACKAGE=freeswitch-meta-all
# Source Dockerfile:
# https://github.com/docker-library/postgres/blob/master/9.4/Dockerfile
# explicitly set user/group IDs
RUN groupadd -r freeswitch --gid=999 && useradd -r -g freeswitch --uid=999 freeswitch
# grab gosu for easy step-down from root
RUN apt-get update && apt-get install -y --no-install-recommends dirmngr gnupg2 ca-certificates wget \
&& gpg2 --keyserver hkp://keyserver.ubuntu.com --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
&& gpg2 --keyserver hkp://keyserver.ubuntu.com --recv-keys 655DA1341B5207915210AFE936B4249FA7B0FB03 \
&& gpg2 --output /usr/share/keyrings/signalwire-freeswitch-repo.gpg --export 655DA1341B5207915210AFE936B4249FA7B0FB03 \
&& rm -rf /var/lib/apt/lists/* \
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/1.2/gosu-$(dpkg --print-architecture)" \
&& wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/1.2/gosu-$(dpkg --print-architecture).asc" \
&& gpg --verify /usr/local/bin/gosu.asc \
&& rm /usr/local/bin/gosu.asc \
&& chmod +x /usr/local/bin/gosu \
&& apt-get purge -y --auto-remove ca-certificates wget dirmngr gnupg2
# make the "en_US.UTF-8" locale so freeswitch will be utf-8 enabled by default
RUN apt-get update && apt-get install -y locales && rm -rf /var/lib/apt/lists/* \
RUN apt-get update -qq \
&& apt-get install -y --no-install-recommends ca-certificates gnupg2 gosu locales wget \
&& localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
ENV LANG en_US.utf8
# https://freeswitch.org/confluence/display/FREESWITCH/Debian
# https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Installation/Linux/Debian_67240088/
RUN apt-get update && apt-get install ca-certificates lsb-release -y --no-install-recommends \
RUN wget --no-verbose --http-user=signalwire --http-password=${TOKEN} \
-O /usr/share/keyrings/signalwire-freeswitch-repo.gpg \
https://freeswitch.signalwire.com/repo/deb/debian-release/signalwire-freeswitch-repo.gpg \
&& echo "machine freeswitch.signalwire.com login signalwire password ${TOKEN}" > /etc/apt/auth.conf \
&& echo "deb [signed-by=/usr/share/keyrings/signalwire-freeswitch-repo.gpg] https://freeswitch.signalwire.com/repo/deb/debian-release/ `lsb_release -sc` main" > /etc/apt/sources.list.d/freeswitch.list \
&& apt-get update && apt-get install -y freeswitch-all \
&& apt-get purge -y --auto-remove ca-certificates lsb-release \
&& echo "deb [signed-by=/usr/share/keyrings/signalwire-freeswitch-repo.gpg] https://freeswitch.signalwire.com/repo/deb/debian-release/ ${DEBIAN_VERSION} main" > /etc/apt/sources.list.d/freeswitch.list \
&& apt-get -qq update \
&& apt-get install -y ${FS_META_PACKAGE} \
&& apt-get purge -y --auto-remove \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
COPY docker-entrypoint.sh /
# Add anything else here
## Ports
# Open the container up to the world.
### 8021 fs_cli, 5060 5061 5080 5081 sip and sips, 64535-65535 rtp
# Document ports used by this container
### 8021 fs_cli, 5060 5061 5080 5081 sip and sips, 5066 ws, 7443 wss, 8081 8082 verto, 16384-32768, 64535-65535 rtp
EXPOSE 8021/tcp
EXPOSE 5060/tcp 5060/udp 5080/tcp 5080/udp
EXPOSE 5061/tcp 5061/udp 5081/tcp 5081/udp
EXPOSE 5066/tcp
EXPOSE 7443/tcp
EXPOSE 5070/udp 5070/tcp
EXPOSE 8081/tcp 8082/tcp
EXPOSE 64535-65535/udp
EXPOSE 16384-32768/udp
# Volumes
## Freeswitch Configuration
VOLUME ["/etc/freeswitch"]
@ -61,11 +66,9 @@ VOLUME ["/tmp"]
COPY build/freeswitch.limits.conf /etc/security/limits.d/
# Healthcheck to make sure the service is running
SHELL ["/bin/bash"]
SHELL ["/bin/bash", "-c"]
HEALTHCHECK --interval=15s --timeout=5s \
CMD fs_cli -x status | grep -q ^UP || exit 1
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["freeswitch"]

View File

@ -140,7 +140,7 @@ BuildRequires: curl-devel >= 7.19
BuildRequires: gcc-c++
BuildRequires: libtool >= 1.5.17
BuildRequires: openssl-devel >= 1.0.1e
BuildRequires: sofia-sip-devel >= 1.13.15
BuildRequires: sofia-sip-devel >= 1.13.17
BuildRequires: spandsp3-devel >= 3.0
BuildRequires: pcre-devel
BuildRequires: speex-devel

View File

@ -1447,6 +1447,11 @@ void vp8_change_config(VP8_COMP *cpi, VP8_CONFIG *oxcf) {
last_h = cpi->oxcf.Height;
prev_number_of_layers = cpi->oxcf.number_of_layers;
if (cpi->initial_width) {
// TODO(https://crbug.com/1486441): Allow changing thread counts; the
// allocation is done once in vp8_create_compressor().
oxcf->multi_threaded = cpi->oxcf.multi_threaded;
}
cpi->oxcf = *oxcf;
switch (cpi->oxcf.Mode) {

View File

@ -123,12 +123,6 @@ int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) {
if (cm->alloc_mi(cm, new_mi_size)) goto fail;
}
if (cm->seg_map_alloc_size < cm->mi_rows * cm->mi_cols) {
// Create the segmentation map structure and set to 0.
free_seg_map(cm);
if (alloc_seg_map(cm, cm->mi_rows * cm->mi_cols)) goto fail;
}
if (cm->above_context_alloc_cols < cm->mi_cols) {
vpx_free(cm->above_context);
cm->above_context = (ENTROPY_CONTEXT *)vpx_calloc(
@ -143,6 +137,12 @@ int vp9_alloc_context_buffers(VP9_COMMON *cm, int width, int height) {
cm->above_context_alloc_cols = cm->mi_cols;
}
if (cm->seg_map_alloc_size < cm->mi_rows * cm->mi_cols) {
// Create the segmentation map structure and set to 0.
free_seg_map(cm);
if (alloc_seg_map(cm, cm->mi_rows * cm->mi_cols)) goto fail;
}
if (vp9_alloc_loop_filter(cm)) goto fail;
return 0;

View File

@ -1915,6 +1915,17 @@ static void alloc_copy_partition_data(VP9_COMP *cpi) {
}
}
static void free_copy_partition_data(VP9_COMP *cpi) {
vpx_free(cpi->prev_partition);
cpi->prev_partition = NULL;
vpx_free(cpi->prev_segment_id);
cpi->prev_segment_id = NULL;
vpx_free(cpi->prev_variance_low);
cpi->prev_variance_low = NULL;
vpx_free(cpi->copied_frame_cnt);
cpi->copied_frame_cnt = NULL;
}
void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
@ -1999,6 +2010,8 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
new_mi_size = cm->mi_stride * calc_mi_size(cm->mi_rows);
if (cm->mi_alloc_size < new_mi_size) {
vp9_free_context_buffers(cm);
vp9_free_pc_tree(&cpi->td);
vpx_free(cpi->mbmi_ext_base);
alloc_compressor_data(cpi);
realloc_segmentation_maps(cpi);
cpi->initial_width = cpi->initial_height = 0;
@ -2014,8 +2027,18 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
update_frame_size(cpi);
if (last_w != cpi->oxcf.width || last_h != cpi->oxcf.height) {
memset(cpi->consec_zero_mv, 0,
cm->mi_rows * cm->mi_cols * sizeof(*cpi->consec_zero_mv));
vpx_free(cpi->consec_zero_mv);
CHECK_MEM_ERROR(
cm, cpi->consec_zero_mv,
vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(*cpi->consec_zero_mv)));
vpx_free(cpi->skin_map);
CHECK_MEM_ERROR(
cm, cpi->skin_map,
vpx_calloc(cm->mi_rows * cm->mi_cols, sizeof(cpi->skin_map[0])));
free_copy_partition_data(cpi);
alloc_copy_partition_data(cpi);
if (cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
vp9_cyclic_refresh_reset_resize(cpi);
rc->rc_1_frame = 0;

View File

@ -0,0 +1,28 @@
#!/usr/bin/perl
use strict;
use warnings;
my $remote_version = `wget --quiet https://data.iana.org/time-zones/tzdb/version --output-document -` =~ s/\n//r;
my $local_version;
if ( open my $in, "<data/version" ) {
$local_version = do { local $/; <$in> };
close $in;
}
my $up_to_date = defined($local_version) && $local_version eq $remote_version;
if ( ! $up_to_date ) {
open my $out, ">data/version";
print $out $remote_version;
close $out;
}
$local_version = $remote_version;
`wget --quiet --timestamping --directory-prefix=data https://data.iana.org/time-zones/tzdb-latest.tar.lz`;
`tar --extract --file=data/tzdb-latest.tar.lz --directory=data`;
`make DESTDIR=../ TZDIR=zones-$local_version --directory=data/tzdb-$local_version posix_only`;
print("Yay. Now you can run\n ./timezone-gen.pl --base=data/zones-$local_version --output=timezones-$local_version.conf.xml")

View File

@ -0,0 +1,4 @@
tzdb-*
zones-*
version
tzdb-latest.tar.lz

View File

@ -0,0 +1,61 @@
#!/usr/bin/perl
sub fixTzstr {
# switch_time.c expects POSIX-style TZ rule, but it won't process quoted TZ
# rules that look like this: <-04>4 or <-04>4<-03>
# See https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03
# Instead it defaults to UTC for these values. Here we process the quoted
# values and convert them into letters. If the zone name has "GMT", we use
# that as the replacement prefix, otherwise a default "STD" is used. Zones
# that have a quoted suffix have their suffix replaced with "DST".
my ($tzstr, $name) = @_;
if ( $tzstr =~ /(<(?<std>[^>]+)>)([^<]+)(?<dst><.+>)?(?<rest>.+)?/ ) {
my ($tzprefix, $tzsuffix, $tzrest, $offset, $offsetprefix) = ("") x 5;
if ( defined($+{std}) ) {
my $std = $+{std};
if ( lc($name) =~ m/gmt/) {
$tzprefix = "GMT";
} else {
$tzprefix = "STD";
}
if ( $std =~ m/\+/ ) {
$offset = sprintf "%d", $std =~ s/\+//r;
$offsetprefix = "-";
} else {
$offset = sprintf "%d", $std =~ s/\-//r;
}
my @chars = split(//, $offset);
if ( @chars > 2 ) {
my $hours = $chars[-3];
if ( defined( $chars[-4] ) ) {
$hours = $chars[-4].$hours;
}
$offset = $hours.":".$chars[-2].$chars[-1];
}
$offset = $offsetprefix.$offset;
}
if ( defined($+{dst}) ) {
$tzsuffix = "DST";
}
if ( defined($+{rest}) ) {
$tzrest = $+{rest};
}
return $tzprefix.$offset.$tzsuffix.$tzrest;
}
return $tzstr;
}
1;

View File

@ -0,0 +1,65 @@
#!/usr/bin/perl
=pod
Tests to verify that the provided modifications to timezone formats produce
the correct results. The first set of tests verify the fixTzstr subroutine
converts the quoted values to something that won't make FreeSWITCH default to
UTC.
The second set of tests confirms that those timezone changes actually produce
the correct timestamps.
Make sure FreeSWITCH already has already loaded the timezones.conf.xml that you
want to test.
To run tests:
TIMEZONES_XML_PATH=path/to/timezones.conf.xml prove tests.pl
=cut
use strict;
use warnings;
use Test::More;
use ESL;
use XML::LibXML::Reader;
require "./fix-tzstr.pl";
use Env qw(TIMEZONES_XML_PATH);
die "The TIMEZONES_XML_PATH environment variable must be set to test timezones." unless ( defined($TIMEZONES_XML_PATH) );
ok( fixTzstr("<-02>2", "doesntmatterhere") eq "STD2" );
ok( fixTzstr("EST5EDT,M3.2.0,M11.1.0", "US/Eastern") eq "EST5EDT,M3.2.0,M11.1.0" );
ok( fixTzstr("<+11>-11", "GMT-11") eq "GMT-11" );
ok( fixTzstr("<-02>2<-01>,M3.5.0/-1,M10.5.0/0", "America/Godthab") eq "STD2DST,M3.5.0/-1,M10.5.0/0" );
my $test_count = 4;
my $tz_fmt = "%Y-%m-%d %H:%M:%S";
my $c = new ESL::ESLconnection("127.0.0.1", "8021", "ClueCon");
$c->api("reloadxml")->getBody();
my $epoch = $c->api("strepoch")->getBody();
run_tests($epoch);
run_tests("1699613236"); # testing DST, add more epochs as needed
sub run_tests {
my $epoch = shift;
my $reader = XML::LibXML::Reader->new(location => $TIMEZONES_XML_PATH);
while ($reader->read) {
my $tag = $reader;
if ( $tag->name eq "zone" && $tag->hasAttributes() ) {
my $zn = $tag->getAttribute("name");
my $cmd = `TZ='$zn' date +'$tz_fmt' --date='\@$epoch'`;
my $sys_time = $cmd =~ s/\n//r;
my $fs_time = $c->api("strftime_tz $zn $epoch|$tz_fmt")->getBody();
ok ( $sys_time eq $fs_time, $zn ) or diag(
" (sys) $sys_time\t(fs) $fs_time"
);
$test_count++;
}
}
}
done_testing($test_count);

View File

@ -1,10 +1,12 @@
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
use XML::Entities;
use HTML::Entities;
require "./fix-tzstr.pl";
my $base = "/usr/share/zoneinfo";
my $output = "timezones.conf.xml";
@ -18,7 +20,7 @@ my $res = GetOptions(
"base=s" => \$base,
"debug+" => \$debug,
"help" => \$help,
"output" => \$output
"output=s" => \$output
);
if ( !$res || $help ) {
print "$0 [--base=/usr/share/zoneinfo] [--output=timezones.conf.xml] [--debug] [--help]\n";
@ -64,7 +66,9 @@ foreach my $name ( sort( keys(%name_to_file) ) ) {
next;
}
$zones{$name} = pop(@strings);
my $tzstr = fixTzstr( pop(@strings), $name );
$zones{$name} = $tzstr;
}
open( my $out, ">$output" );
@ -83,7 +87,7 @@ foreach my $zone ( sort( keys(%zones) ) ) {
}
$lastprefix = $newprefix;
print $out "\t<zone name=\"$zone\" value=\"$str\" />\n";
print $out " " x 8, "<zone name=\"$zone\" value=\"$str\" />\n";
}
print $out " " x 4, "</timezones>\n";
print $out "</configuration>\n";

View File

@ -1104,34 +1104,32 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i
buffer->length = default_buffer_size;
buffer->format = format;
buffer->hooks = *hooks;
if (buffer->buffer == NULL)
{
if (buffer->buffer == NULL) {
goto fail;
}
/* print the value */
if (!print_value(item, buffer))
{
if (!print_value(item, buffer)) {
goto fail;
}
update_offset(buffer);
/* check if reallocate is available */
if (hooks->reallocate != NULL)
{
if (hooks->reallocate != NULL) {
printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1);
if (printed == NULL) {
goto fail;
}
buffer->buffer = NULL;
}
else /* otherwise copy the JSON over to a new buffer */
{
} else { /* otherwise copy the JSON over to a new buffer */
printed = (unsigned char*) hooks->allocate(buffer->offset + 1);
if (printed == NULL)
{
if (printed == NULL) {
goto fail;
}
memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1));
printed[buffer->offset] = '\0'; /* just to be sure */
@ -1142,16 +1140,10 @@ static unsigned char *print(const cJSON * const item, cJSON_bool format, const i
return printed;
fail:
if (buffer->buffer != NULL)
{
if (buffer->buffer != NULL) {
hooks->deallocate(buffer->buffer);
}
if (printed != NULL)
{
hooks->deallocate(printed);
}
return NULL;
}
@ -1942,33 +1934,41 @@ static cJSON_bool add_item_to_object(cJSON * const object, const char * const st
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
{
add_item_to_object(object, string, item, &global_hooks, false);
cJSON_bool res = add_item_to_object(object, string, item, &global_hooks, false);
(void)res;
}
/* Add an item to an object with constant string as key */
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item)
{
add_item_to_object(object, string, item, &global_hooks, true);
cJSON_bool res = add_item_to_object(object, string, item, &global_hooks, true);
(void)res;
}
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)
{
cJSON_bool res;
if (array == NULL)
{
return;
}
add_item_to_array(array, create_reference(item, &global_hooks));
res = add_item_to_array(array, create_reference(item, &global_hooks));
(void)res;
}
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item)
{
cJSON_bool res;
if ((object == NULL) || (string == NULL))
{
return;
}
add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
res = add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false);
(void)res;
}
CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name)

View File

@ -103,6 +103,8 @@ typedef struct icand_s {
switch_port_t rport;
char *generation;
uint8_t ready;
uint8_t responsive;
uint8_t use_candidate;
} icand_t;
#define MAX_CAND 50

View File

@ -1316,15 +1316,15 @@ void conference_loop_output(conference_member_t *member)
uint32_t flush_len;
uint32_t low_count, bytes;
call_list_t *call_list, *cp;
switch_codec_implementation_t read_impl = { 0 }, real_read_impl = { 0 };
switch_codec_implementation_t real_read_impl = { 0 };
int sanity;
switch_core_session_get_read_impl(member->session, &read_impl);
switch_core_session_get_read_impl(member->session, &member->read_impl);
switch_core_session_get_real_read_impl(member->session, &real_read_impl);
channel = switch_core_session_get_channel(member->session);
interval = read_impl.microseconds_per_packet / 1000;
interval = member->read_impl.microseconds_per_packet / 1000;
samples = switch_samples_per_packet(member->conference->rate, interval);
//csamples = samples;
tsamples = real_read_impl.samples_per_packet;

View File

@ -1363,7 +1363,7 @@ void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, i
void conference_jlist(conference_obj_t *conference, cJSON *json_conferences)
{
conference_member_t *member = NULL;
static cJSON *json_conference, *json_conference_variables, *json_conference_members, *json_conference_member, *json_conference_member_flags;
cJSON *json_conference, *json_conference_variables, *json_conference_members, *json_conference_member, *json_conference_member_flags;
switch_event_header_t *hp;
switch_assert(conference != NULL);

View File

@ -113,7 +113,7 @@ static int db_is_up(switch_pgsql_handle_t *handle)
char *err_str = NULL;
int max_tries = DEFAULT_PGSQL_RETRIES;
int code = 0;
int recon = 0;
switch_status_t recon = SWITCH_STATUS_FALSE;
switch_byte_t sanity = 255;
if (handle) {
@ -128,6 +128,7 @@ top:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Handle\n");
goto done;
}
if (!handle->con) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No DB Connection\n");
goto done;
@ -141,6 +142,7 @@ top:
switch_yield(1);
continue;
}
break;
}
@ -158,6 +160,7 @@ reset:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "PQstatus returned bad connection -- reconnection failed!\n");
goto error;
}
handle->state = SWITCH_PGSQL_STATE_CONNECTED;
handle->sock = PQsocket(handle->con);
}
@ -193,6 +196,7 @@ error:
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "The connection could not be re-established");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "The connection could not be re-established\n");
}
if (!max_tries) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Additional-Info", "Giving up!");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Giving up!\n");

View File

@ -488,7 +488,7 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
if (sofia_test_pflag(tech_pvt->profile, PFLAG_DESTROY)) {
sofia_set_flag(tech_pvt, TFLAG_BYE);
} else if (tech_pvt->nh && !sofia_test_flag(tech_pvt, TFLAG_BYE)) {
char reason[128] = "";
char *reason = switch_core_session_sprintf(session, "");
char *bye_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_BYE_HEADER_PREFIX);
const char *val = NULL;
const char *max_forwards = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE);
@ -499,15 +499,15 @@ switch_status_t sofia_on_hangup(switch_core_session_t *session)
if (!val || switch_false(val)) {
if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_reason"))) {
switch_snprintf(reason, sizeof(reason), "%s", val);
reason = switch_core_session_sprintf(session, "%s", val);
} else {
if ((switch_channel_test_flag(channel, CF_INTERCEPT) || cause == SWITCH_CAUSE_PICKED_OFF || cause == SWITCH_CAUSE_LOSE_RACE)
&& !switch_true(switch_channel_get_variable(channel, "ignore_completed_elsewhere"))) {
switch_snprintf(reason, sizeof(reason), "SIP;cause=200;text=\"Call completed elsewhere\"");
reason = switch_core_session_sprintf(session, "SIP;cause=200;text=\"Call completed elsewhere\"");
} else if (cause > 0 && cause < 128) {
switch_snprintf(reason, sizeof(reason), "Q.850;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause));
reason = switch_core_session_sprintf(session, "Q.850;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause));
} else {
switch_snprintf(reason, sizeof(reason), "SIP;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause));
reason = switch_core_session_sprintf(session, "SIP;cause=%d;text=\"%s\"", cause, switch_channel_cause2str(cause));
}
}
}

View File

@ -45237,6 +45237,50 @@ SWIGEXPORT unsigned char SWIGSTDCALL CSharp_FreeSWITCHfNative_icand_t_ready_get_
}
SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_icand_t_responsive_set___(void * jarg1, unsigned char jarg2) {
icand_s *arg1 = (icand_s *) 0 ;
uint8_t arg2 ;
arg1 = (icand_s *)jarg1;
arg2 = (uint8_t)jarg2;
if (arg1) (arg1)->responsive = arg2;
}
SWIGEXPORT unsigned char SWIGSTDCALL CSharp_FreeSWITCHfNative_icand_t_responsive_get___(void * jarg1) {
unsigned char jresult ;
icand_s *arg1 = (icand_s *) 0 ;
uint8_t result;
arg1 = (icand_s *)jarg1;
result = (uint8_t) ((arg1)->responsive);
jresult = result;
return jresult;
}
SWIGEXPORT void SWIGSTDCALL CSharp_FreeSWITCHfNative_icand_t_use_candidate_set___(void * jarg1, unsigned char jarg2) {
icand_s *arg1 = (icand_s *) 0 ;
uint8_t arg2 ;
arg1 = (icand_s *)jarg1;
arg2 = (uint8_t)jarg2;
if (arg1) (arg1)->use_candidate = arg2;
}
SWIGEXPORT unsigned char SWIGSTDCALL CSharp_FreeSWITCHfNative_icand_t_use_candidate_get___(void * jarg1) {
unsigned char jresult ;
icand_s *arg1 = (icand_s *) 0 ;
uint8_t result;
arg1 = (icand_s *)jarg1;
result = (uint8_t) ((arg1)->use_candidate);
jresult = result;
return jresult;
}
SWIGEXPORT void * SWIGSTDCALL CSharp_FreeSWITCHfNative_new_icand_t___() {
void * jresult ;
icand_s *result = 0 ;

View File

@ -26316,6 +26316,18 @@ class freeswitchPINVOKE {
[global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_icand_t_ready_get___")]
public static extern byte icand_t_ready_get(global::System.Runtime.InteropServices.HandleRef jarg1);
[global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_icand_t_responsive_set___")]
public static extern void icand_t_responsive_set(global::System.Runtime.InteropServices.HandleRef jarg1, byte jarg2);
[global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_icand_t_responsive_get___")]
public static extern byte icand_t_responsive_get(global::System.Runtime.InteropServices.HandleRef jarg1);
[global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_icand_t_use_candidate_set___")]
public static extern void icand_t_use_candidate_set(global::System.Runtime.InteropServices.HandleRef jarg1, byte jarg2);
[global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_icand_t_use_candidate_get___")]
public static extern byte icand_t_use_candidate_get(global::System.Runtime.InteropServices.HandleRef jarg1);
[global::System.Runtime.InteropServices.DllImport("mod_managed", EntryPoint="CSharp_FreeSWITCHfNative_new_icand_t___")]
public static extern global::System.IntPtr new_icand_t();
@ -28339,6 +28351,26 @@ public class icand_t : global::System.IDisposable {
}
}
public byte responsive {
set {
freeswitchPINVOKE.icand_t_responsive_set(swigCPtr, value);
}
get {
byte ret = freeswitchPINVOKE.icand_t_responsive_get(swigCPtr);
return ret;
}
}
public byte use_candidate {
set {
freeswitchPINVOKE.icand_t_use_candidate_set(swigCPtr, value);
}
get {
byte ret = freeswitchPINVOKE.icand_t_use_candidate_get(swigCPtr);
return ret;
}
}
public icand_t() : this(freeswitchPINVOKE.new_icand_t(), true) {
}

View File

@ -722,13 +722,10 @@ SWITCH_DECLARE(payload_map_t *) switch_core_media_add_payload_map(switch_core_se
exists = (type == pmap->type && !strcasecmp(name, pmap->iananame) && pmap->pt == pt && (!pmap->rate || rate == pmap->rate) && (!pmap->ptime || pmap->ptime == ptime));
break;
case SWITCH_MEDIA_TYPE_VIDEO:
if (sdp_type == SDP_TYPE_RESPONSE) {
exists = (pmap->sdp_type == SDP_TYPE_REQUEST && type == pmap->type && !strcasecmp(name, pmap->iananame));
} else {
exists = (type == pmap->type && !strcasecmp(name, pmap->iananame));
}
exists = (pmap->sdp_type == SDP_TYPE_REQUEST && type == pmap->type && !strcasecmp(name, pmap->iananame));
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "CHECK PMAP %s:%s %d %s:%s %d ... %d\n",
name, sdp_type == SDP_TYPE_REQUEST ? "REQ" : "RES", pt,
name, "RES", pt,
pmap->iananame, pmap->sdp_type == SDP_TYPE_REQUEST ? "REQ" : "RES", pmap->pt, exists);
@ -2069,13 +2066,13 @@ SWITCH_DECLARE(switch_status_t) switch_media_handle_create(switch_media_handle_t
switch_mutex_init(&session->media_handle->control_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO].ssrc =
(uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO] + (uint32_t) time(NULL));
(uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_AUDIO] + (switch_time_t) time(NULL));
session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO].ssrc =
(uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO] + (uint32_t) time(NULL) / 2);
(uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_VIDEO] + (switch_time_t) time(NULL) / 2);
session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT].ssrc =
(uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT] + (uint32_t) time(NULL) / 2);
(uint32_t) ((intptr_t) &session->media_handle->engines[SWITCH_MEDIA_TYPE_TEXT] + (switch_time_t) time(NULL) / 2);
@ -2524,7 +2521,7 @@ static void check_jb_sync(switch_core_session_t *session)
}
if (!jb_sync_msec && frames) {
jb_sync_msec = (double)(1000 / fps) * frames;
jb_sync_msec = ((double)1000 / fps) * frames;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session),
@ -4624,9 +4621,10 @@ static void check_stream_changes(switch_core_session_t *session, const char *r_s
{
switch_core_session_t *other_session = NULL;
switch_core_session_message_t *msg;
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_core_session_get_partner(session, &other_session);
status = switch_core_session_get_partner(session, &other_session);
(void)status;
if (switch_channel_test_flag(session->channel, CF_STREAM_CHANGED)) {
switch_channel_clear_flag(session->channel, CF_STREAM_CHANGED);
@ -4662,13 +4660,15 @@ static void check_stream_changes(switch_core_session_t *session, const char *r_s
if (switch_channel_test_flag(other_session->channel, CF_AWAITING_STREAM_CHANGE)) {
uint8_t proceed = 1;
const char *sdp_in, *other_ep;
uint8_t res = 0;
if ((other_ep = switch_channel_get_variable(session->channel, "ep_codec_string"))) {
switch_channel_set_variable(other_session->channel, "codec_string", other_ep);
}
sdp_in = switch_channel_get_variable(other_session->channel, SWITCH_R_SDP_VARIABLE);
switch_core_media_negotiate_sdp(other_session, sdp_in, &proceed, SDP_TYPE_REQUEST);
res = switch_core_media_negotiate_sdp(other_session, sdp_in, &proceed, SDP_TYPE_REQUEST);
(void)res;
switch_core_media_activate_rtp(other_session);
msg = switch_core_session_alloc(other_session, sizeof(*msg));
msg->message_id = SWITCH_MESSAGE_INDICATE_RESPOND;
@ -6732,6 +6732,7 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
float fps = 15.0f;
switch_image_t *last_frame = NULL;
int last_w = 0, last_h = 0, kps = 0;
switch_status_t res;
if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
return NULL;
@ -6739,10 +6740,12 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
if (!(smh = session->media_handle)) {
switch_core_session_rwunlock(session);
return NULL;
}
switch_core_session_get_partner(session, &b_session);
res = switch_core_session_get_partner(session, &b_session);
(void)res;
switch_channel_set_flag(session->channel, CF_VIDEO_WRITING);
@ -6763,7 +6766,6 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
fr.buflen = buflen - 12;
switch_core_media_gen_key_frame(session);
if (smh->video_write_fh) {
if (smh->video_write_fh->mm.fps) {
fps = smh->video_write_fh->mm.fps;
@ -6803,8 +6805,6 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
switch_channel_up_nosig(session->channel) && smh->video_write_fh && switch_test_flag(smh->video_write_fh, SWITCH_FILE_OPEN)) {
switch_status_t wstatus = SWITCH_STATUS_FALSE;
switch_core_timer_next(&timer);
switch_mutex_lock(v_engine->mh.file_write_mutex);
@ -6847,12 +6847,14 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
switch_set_flag_locked(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF);
}
}
switch_mutex_unlock(v_engine->mh.file_write_mutex);
}
if (last_frame) {
int x = 0;
switch_rgb_color_t bgcolor;
switch_color_set_rgb(&bgcolor, "#000000");
switch_img_fill(last_frame, 0, 0, last_frame->d_w, last_frame->d_h, &bgcolor);
fr.img = last_frame;
@ -6863,12 +6865,12 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
fr.flags = SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP|SFF_RAW_RTP_PARSE_FRAME;
switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0);
}
switch_core_media_gen_key_frame(session);
switch_core_session_request_video_refresh(session);
switch_img_free(&last_frame);
}
switch_core_timer_destroy(&timer);
switch_core_session_rwunlock(session);
@ -6878,7 +6880,6 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void
switch_core_session_rwunlock(b_session);
}
v_engine->thread_write_lock = 0;
switch_mutex_unlock(smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]);
@ -10525,7 +10526,7 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
}
if (!smh->owner_id) {
smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) - port;
smh->owner_id = (uint32_t)(switch_time_t)switch_epoch_time_now(NULL) - port;
}
if (!smh->session_id) {
@ -11835,7 +11836,7 @@ SWITCH_DECLARE(void) switch_core_media_set_udptl_image_sdp(switch_core_session_t
}
if (!smh->owner_id) {
smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) - port;
smh->owner_id = (uint32_t)(switch_time_t)switch_epoch_time_now(NULL) - port;
}
if (!smh->session_id) {
@ -12049,7 +12050,7 @@ SWITCH_DECLARE(void) switch_core_media_patch_sdp(switch_core_session_t *session)
family = strchr(smh->mparams->sipip, ':') ? "IP6" : "IP4";
if (!smh->owner_id) {
smh->owner_id = (uint32_t) switch_epoch_time_now(NULL) * 31821U + 13849U;
smh->owner_id = (uint32_t)(switch_time_t) switch_epoch_time_now(NULL) * 31821U + 13849U;
}
if (!smh->session_id) {
@ -13587,6 +13588,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess
if (zstr(attr->a_name)) {
continue;
}
if (!strcasecmp(attr->a_name, "ptime")) {
dptime = atoi(attr->a_value);
break;
@ -13599,22 +13601,27 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess
if ((m->m_type == sdp_media_audio || m->m_type == sdp_media_video) && m->m_port) {
for (map = m->m_rtpmaps; map; map = map->rm_next) {
int found = 0;
for (attr = m->m_attributes; attr && found < 2; attr = attr->a_next) {
if (zstr(attr->a_name)) {
continue;
}
if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
ptime = atoi(attr->a_value);
found++;
}
if (!strcasecmp(attr->a_name, "rtcp-mux")) {
if (switch_channel_var_true(channel, "rtcp_mux_auto_detect")) {
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "setting rtcp-mux from sdp\n");
switch_channel_set_variable(channel, "rtcp_mux", "true");
}
found++;
}
}
switch_core_media_add_payload_map(session,
m->m_type == sdp_media_audio ? SWITCH_MEDIA_TYPE_AUDIO : SWITCH_MEDIA_TYPE_VIDEO,
map->rm_encoding,
@ -13640,11 +13647,13 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess
if (zstr(attr->a_name)) {
continue;
}
if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) {
ptime = atoi(attr->a_value);
break;
}
}
connection = sdp->sdp_connection;
if (m->m_connections) {
connection = m->m_connections;
@ -13658,7 +13667,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND || prefer_sdp) {
for (map = m->m_rtpmaps; map; map = map->rm_next) {
if (map->rm_pt > 127 || already_did[map->rm_pt]) {
if (already_did[map->rm_pt]) {
continue;
}
@ -13679,19 +13688,20 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess
if (match) {
add_audio_codec(map, imp, ptime, buf, sizeof(buf));
}
}
}
} else {
for (i = 0; i < num_codecs; i++) {
const switch_codec_implementation_t *imp = codecs[i];
if (imp->codec_type != SWITCH_CODEC_TYPE_AUDIO || imp->ianacode > 127 || already_did[imp->ianacode]) {
continue;
}
for (map = m->m_rtpmaps; map; map = map->rm_next) {
if (map->rm_pt > 127 || already_did[map->rm_pt]) {
if (already_did[map->rm_pt]) {
continue;
}
@ -13724,11 +13734,10 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess
break;
}
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND || prefer_sdp) {
for (map = m->m_rtpmaps; map; map = map->rm_next) {
if (map->rm_pt > 127 || already_did[map->rm_pt]) {
if (already_did[map->rm_pt]) {
continue;
}
@ -13752,11 +13761,11 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess
} else {
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s", imp->modname, imp->iananame);
}
already_did[imp->ianacode] = 1;
}
}
}
} else {
for (i = 0; i < num_codecs; i++) {
const switch_codec_implementation_t *imp = codecs[i];
@ -13772,7 +13781,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess
for (map = m->m_rtpmaps; map; map = map->rm_next) {
if (map->rm_pt > 127 || already_did[map->rm_pt]) {
if (already_did[map->rm_pt]) {
continue;
}
@ -13793,6 +13802,7 @@ static void switch_core_media_set_r_sdp_codec_string(switch_core_session_t *sess
} else {
switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ",%s.%s", imp->modname, imp->iananame);
}
already_did[imp->ianacode] = 1;
}
}

View File

@ -501,9 +501,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_destroy_memory_pool(switch_m
#if APR_POOL_DEBUG
fspr_pool_destroy_debug(tmp_pool, func);
#else
fspr_pool_destroy(tmp_pool);
if (tmp_pool) {
fspr_pool_destroy(tmp_pool);
}
#endif
#ifdef USE_MEM_LOCK
switch_mutex_unlock(memory_manager.mem_lock);
#endif
}

View File

@ -702,7 +702,7 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t
case SCDB_TYPE_ODBC:
{
type = "ODBC";
status = switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, sql, NULL, &errmsg);
status = switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, sql, NULL, &errmsg) == SWITCH_ODBC_SUCCESS ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
}
break;
case SCDB_TYPE_CORE_DB:
@ -904,7 +904,7 @@ SWITCH_DECLARE(char *) switch_cache_db_execute_sql2str(switch_cache_db_handle_t
break;
case SCDB_TYPE_ODBC:
{
status = switch_odbc_handle_exec_string(dbh->native_handle.odbc_dbh, sql, str, len, err);
status = switch_odbc_handle_exec_string(dbh->native_handle.odbc_dbh, sql, str, len, err) == SWITCH_ODBC_SUCCESS ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
}
break;
case SCDB_TYPE_DATABASE_INTERFACE:
@ -1189,7 +1189,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_event_callback(switc
break;
case SCDB_TYPE_ODBC:
{
status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, helper_callback, &h, err);
status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, helper_callback, &h, err) == SWITCH_ODBC_SUCCESS ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
}
break;
case SCDB_TYPE_CORE_DB:
@ -1248,7 +1248,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_event_callback_err(s
break;
case SCDB_TYPE_ODBC:
{
status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, helper_callback, &h, err);
status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, helper_callback, &h, err) == SWITCH_ODBC_SUCCESS ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
if (err && *err) {
(*err_callback)(pdata, (const char*)*err);
}
@ -1305,7 +1305,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cach
break;
case SCDB_TYPE_ODBC:
{
status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, callback, pdata, err);
status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, callback, pdata, err) == SWITCH_ODBC_SUCCESS ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
}
break;
case SCDB_TYPE_CORE_DB:
@ -1358,7 +1358,7 @@ SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback_err(switch_
break;
case SCDB_TYPE_ODBC:
{
status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, callback, pdata, err);
status = switch_odbc_handle_callback_exec(dbh->native_handle.odbc_dbh, sql, callback, pdata, err) == SWITCH_ODBC_SUCCESS ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
if (err && *err) {
(*err_callback)(pdata, (const char*)*err);
}
@ -2065,6 +2065,7 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm)
switch_status_t status;
uint32_t ttl = 0;
uint32_t i;
switch_status_t res;
if (!zstr(qm->pre_trans_execute)) {
switch_cache_db_execute_sql_real(qm->event_db, qm->pre_trans_execute, &errmsg);
@ -2126,7 +2127,8 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm)
for (i = 0; (qm->max_trans == 0 || ttl <= qm->max_trans) && (i < qm->numq); i++) {
switch_mutex_lock(qm->mutex);
switch_queue_trypop(qm->sql_queue[i], &pop);
res = switch_queue_trypop(qm->sql_queue[i], &pop);
(void)res;
switch_mutex_unlock(qm->mutex);
if (pop) break;
}
@ -2138,6 +2140,7 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm)
switch_mutex_unlock(qm->mutex);
ttl++;
}
switch_safe_free(pop);
if (status != SWITCH_STATUS_SUCCESS) break;
} else {
@ -2153,7 +2156,6 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm)
}
}
end:
switch(qm->event_db->type) {
@ -2190,11 +2192,11 @@ static uint32_t do_trans(switch_sql_queue_manager_t *qm)
}
}
switch_mutex_lock(qm->mutex);
for (i = 0; i < qm->numq; i++) {
qm->written[i] = qm->pre_written[i];
}
switch_mutex_unlock(qm->mutex);
return ttl;

View File

@ -98,6 +98,7 @@ SWITCH_DECLARE(Event *) EventConsumer::pop(int block, int timeout)
void *pop = NULL;
Event *ret = NULL;
switch_event_t *event;
switch_status_t res;
if (!ready) {
return NULL;
@ -105,14 +106,16 @@ SWITCH_DECLARE(Event *) EventConsumer::pop(int block, int timeout)
if (block) {
if (timeout > 0) {
switch_queue_pop_timeout(events, &pop, (switch_interval_time_t) timeout * 1000); // millisec rather than microsec
res = switch_queue_pop_timeout(events, &pop, (switch_interval_time_t) timeout * 1000); // millisec rather than microsec
} else {
switch_queue_pop(events, &pop);
res = switch_queue_pop(events, &pop);
}
} else {
switch_queue_trypop(events, &pop);
res = switch_queue_trypop(events, &pop);
}
(void)res;
if ((event = (switch_event_t *) pop)) {
ret = new Event(event, 1);
}
@ -138,9 +141,7 @@ SWITCH_DECLARE(void) EventConsumer::cleanup()
node_index = 0;
if (events) {
switch_queue_interrupt_all(events);
}
switch_queue_interrupt_all(events);
while(switch_queue_trypop(events, &pop) == SWITCH_STATUS_SUCCESS) {
switch_event_t *event = (switch_event_t *) pop;

View File

@ -64,6 +64,7 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_mime(switch_event_t *event,
curl_mime *mime = NULL;
curl_mimepart *part = NULL;
uint8_t added = 0;
switch_CURLcode curl_code = CURLE_OK;
#else
struct curl_httppost *formpost=NULL;
struct curl_httppost *lastptr=NULL;
@ -98,9 +99,21 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_mime(switch_event_t *event,
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
part = curl_mime_addpart(mime);
curl_mime_name(part, pname);
curl_mime_filename(part, fname);
curl_mime_filedata(part, hp->value);
if ((curl_code = curl_mime_name(part, pname))) {
free(pname);
goto error;
}
if ((curl_code = curl_mime_filename(part, fname))) {
free(pname);
goto error;
}
if ((curl_code = curl_mime_filedata(part, hp->value))) {
free(pname);
goto error;
}
added++;
#else
curl_formadd(&formpost,
@ -117,8 +130,14 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_mime(switch_event_t *event,
} else {
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
part = curl_mime_addpart(mime);
curl_mime_name(part, hp->name);
curl_mime_data(part, hp->value, CURL_ZERO_TERMINATED);
if ((curl_code = curl_mime_name(part, hp->name))) {
goto error;
}
if ((curl_code = curl_mime_data(part, hp->value, CURL_ZERO_TERMINATED))) {
goto error;
}
added++;
#else
curl_formadd(&formpost,
@ -131,6 +150,11 @@ SWITCH_DECLARE(switch_status_t) switch_curl_process_mime(switch_event_t *event,
}
#if defined(LIBCURL_VERSION_NUM) && (LIBCURL_VERSION_NUM >= 0x073800)
error:
if (curl_code) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CURL error occured. Error code: %d Error msg: [%s]\n", curl_code, switch_curl_easy_strerror(curl_code));
}
if (!added) {
curl_mime_free(mime);
mime = NULL;

View File

@ -553,6 +553,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void)
switch_hash_index_t *hi;
const void *var;
void *val;
switch_status_t res;
if (switch_core_test_flag(SCF_MINIMAL)) {
return SWITCH_STATUS_SUCCESS;
@ -565,7 +566,8 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void)
unsub_all_switch_event_channel();
if (EVENT_CHANNEL_DISPATCH_QUEUE) {
switch_queue_trypush(EVENT_CHANNEL_DISPATCH_QUEUE, NULL);
res = switch_queue_trypush(EVENT_CHANNEL_DISPATCH_QUEUE, NULL);
(void)res;
switch_queue_interrupt_all(EVENT_CHANNEL_DISPATCH_QUEUE);
}
@ -573,10 +575,10 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping dispatch queues\n");
for(x = 0; x < (uint32_t)DISPATCH_THREAD_COUNT; x++) {
switch_queue_trypush(EVENT_DISPATCH_QUEUE, NULL);
res = switch_queue_trypush(EVENT_DISPATCH_QUEUE, NULL);
(void)res;
}
switch_queue_interrupt_all(EVENT_DISPATCH_QUEUE);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Stopping dispatch threads\n");
@ -595,6 +597,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_shutdown(void)
if (THREAD_COUNT == last) {
x++;
}
last = THREAD_COUNT;
}

View File

@ -1788,6 +1788,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_
if (switch_channel_test_flag(channel, CF_MEDIA_TRANS)) {
switch_core_session_rwunlock(session);
return SWITCH_STATUS_INUSE;
}
@ -1798,6 +1799,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_
}
if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
switch_status_t res = SWITCH_STATUS_SUCCESS;
status = SWITCH_STATUS_SUCCESS;
/* If we had early media in bypass mode before, it is no longer relevant */
@ -1816,6 +1819,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_
if (switch_core_session_receive_message(session, &msg) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't re-establsh media on %s\n", switch_channel_get_name(channel));
switch_core_session_rwunlock(session);
return SWITCH_STATUS_GENERR;
}
@ -1832,7 +1836,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_
switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL);
switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
res = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
}
if ((flags & SMF_REBRIDGE)
@ -1844,10 +1848,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_
switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL);
switch_core_session_read_frame(other_session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
res = switch_core_session_read_frame(other_session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
switch_channel_clear_state_handler(other_channel, NULL);
switch_core_session_rwunlock(other_session);
}
(void)res;
if (other_channel) {
switch_channel_clear_state_handler(channel, NULL);
}
@ -1862,6 +1869,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_
} else {
switch_ivr_uuid_bridge(uuid, other_uuid);
}
switch_channel_wait_for_flag(channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL);
switch_channel_wait_for_flag(other_channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL);
}
@ -2806,11 +2814,13 @@ SWITCH_DECLARE(int) switch_ivr_set_xml_call_stats(switch_xml_t xml, switch_core_
static int switch_ivr_set_xml_chan_var(switch_xml_t xml, const char *var, const char *val, int off)
{
char *data;
switch_size_t dlen = strlen(val) * 3 + 1;
switch_size_t dlen;
switch_xml_t variable;
if (!val) val = "";
dlen = strlen(val) * 3 + 1;
if (!zstr(var) && ((variable = switch_xml_add_child_d(xml, var, off++)))) {
if ((data = malloc(dlen))) {
memset(data, 0, dlen);

View File

@ -474,7 +474,7 @@ static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachin
if (is_timeout) {
if (both_bp) {
r_bp = exact_bp ? exact_bp : both_bp;
r_bp = exact_bp;
}
}

View File

@ -320,8 +320,10 @@ static int check_per_channel_timeouts(originate_global_t *oglobals,
delayed_min = oglobals->originate_status[i].per_channel_delay_start;
}
}
early_exit_time = delayed_min - (uint32_t) elapsed;
early_exit_time = delayed_min - (uint32_t)(switch_time_t) elapsed;
}
for (i = 0; i < max; i++) {
if (oglobals->originate_status[i].peer_channel && oglobals->originate_status[i].per_channel_delay_start &&
(elapsed > oglobals->originate_status[i].per_channel_delay_start || active_channels == 0)) {
@ -334,6 +336,7 @@ static int check_per_channel_timeouts(originate_global_t *oglobals,
oglobals->originate_status[i].per_channel_timelimit_sec = 1;
}
}
if (oglobals->originate_status[i].per_channel_progress_timelimit_sec) {
if (oglobals->originate_status[i].per_channel_progress_timelimit_sec > early_exit_time) {
/* IN theory this check is not needed ( should just be if !0 then -= with no else), if its not 0 it should always be greater.... */
@ -342,6 +345,7 @@ static int check_per_channel_timeouts(originate_global_t *oglobals,
oglobals->originate_status[i].per_channel_progress_timelimit_sec = 1;
}
}
oglobals->originate_status[i].per_channel_delay_start -= delayed_min;
} else {
oglobals->originate_status[i].per_channel_delay_start = 0;
@ -1305,7 +1309,7 @@ static switch_status_t setup_ringback(originate_global_t *oglobals, originate_st
}
}
if (oglobals->session && (read_codec = switch_core_session_get_read_codec(oglobals->session))) {
if ((read_codec = switch_core_session_get_read_codec(oglobals->session))) {
if (ringback_data && switch_is_file_path(ringback_data)) {
if (!(strrchr(ringback_data, '.') || strstr(ringback_data, SWITCH_URL_SEPARATOR))) {
ringback->asis++;
@ -4961,9 +4965,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_orig_and_bridge(switch_cor
switch_ivr_multi_threaded_bridge(session, peer_session, func, a_key, b_key);
}
if (peer_session) {
switch_core_session_rwunlock(peer_session);
}
switch_core_session_rwunlock(peer_session);
}
return status;
@ -5026,9 +5028,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_orig_and_bridge(switch_core_session_t
switch_ivr_multi_threaded_bridge(session, peer_session, func, a_key, b_key);
}
if (peer_session) {
switch_core_session_rwunlock(peer_session);
}
switch_core_session_rwunlock(peer_session);
}
return status;

View File

@ -3202,6 +3202,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_soft_hold(switch_core_session_t *sess
const char *other_uuid, *moh = NULL;
int moh_br = 0;
switch_input_args_t args = { 0 };
switch_status_t res;
args.input_callback = hold_on_dtmf;
args.buf = (void *) unhold_key;
args.buflen = (uint32_t) strlen(unhold_key);
@ -3232,11 +3234,13 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_soft_hold(switch_core_session_t *sess
}
if (!zstr(moh) && strcasecmp(moh, "silence")) {
switch_ivr_play_file(session, NULL, moh, &args);
res = switch_ivr_play_file(session, NULL, moh, &args);
} else {
switch_ivr_collect_digits_callback(session, &args, 0, 0);
res = switch_ivr_collect_digits_callback(session, &args, 0, 0);
}
(void)res;
if (moh_br) {
switch_channel_stop_broadcast(other_channel);
}
@ -3246,10 +3250,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_soft_hold(switch_core_session_t *sess
return SWITCH_STATUS_SUCCESS;
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Channel %s is not in a bridge\n", switch_channel_get_name(channel));
return SWITCH_STATUS_FALSE;
}

View File

@ -1109,17 +1109,19 @@ SWITCH_DECLARE(void) switch_jb_set_session(switch_jb_t *jb, switch_core_session_
jb->codec = switch_core_session_get_read_codec(session);
jb->session = session;
jb->channel = switch_core_session_get_channel(session);
if (!strcmp(jb->codec->implementation->iananame, "opus")) {
if (switch_channel_var_true(jb->channel, "rtp_jitter_buffer_accelerate")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "codec is %s, accelerate on\n", jb->codec->implementation->iananame);
jb->elastic = SWITCH_TRUE;
if (jb->type == SJB_AUDIO) {
if (!strcmp(jb->codec->implementation->iananame, "opus")) {
if (switch_channel_var_true(jb->channel, "rtp_jitter_buffer_accelerate")) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "audio codec is %s, accelerate on\n", jb->codec->implementation->iananame);
jb->elastic = SWITCH_TRUE;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "audio codec is %s, accelerate off\n", jb->codec->implementation->iananame);
jb->elastic = SWITCH_FALSE;
}
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "codec is %s, accelerate off\n", jb->codec->implementation->iananame);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "audio codec is not Opus: %s\n", jb->codec->implementation->iananame);
jb->elastic = SWITCH_FALSE;
}
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "codec not opus: %s\n", jb->codec->implementation->iananame);
jb->elastic = SWITCH_FALSE;
}
if (jb->type == SJB_VIDEO && !switch_test_flag(jb, SJB_QUEUE_ONLY) &&
@ -1717,20 +1719,13 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
}
}
if (node) {
status = SWITCH_STATUS_SUCCESS;
*packet = node->packet;
*len = node->len;
jb->last_len = *len;
packet->header.version = 2;
hide_node(node, SWITCH_TRUE);
*packet = node->packet;
*len = node->len;
jb->last_len = *len;
packet->header.version = 2;
hide_node(node, SWITCH_TRUE);
jb_debug(jb, 2, "GET packet ts:%u seq:%u %s\n", ntohl(packet->header.ts), ntohs(packet->header.seq), packet->header.m ? " <MARK>" : "");
} else {
status = SWITCH_STATUS_MORE_DATA;
}
jb_debug(jb, 2, "GET packet ts:%u seq:%u %s\n", ntohl(packet->header.ts), ntohs(packet->header.seq), packet->header.m ? " <MARK>" : "");
end:

View File

@ -254,10 +254,11 @@ typedef struct {
uint8_t sending;
uint8_t ready;
uint8_t rready;
uint8_t init;
uint8_t initializing;
int missed_count;
char last_sent_id[13];
switch_time_t last_ok;
uint8_t cand_responsive;
} switch_rtp_ice_t;
struct switch_rtp;
@ -401,7 +402,6 @@ struct switch_rtp {
char *eff_remote_host_str;
switch_time_t first_stun;
switch_time_t last_stun;
uint32_t wrong_addrs;
uint32_t samples_per_interval;
uint32_t samples_per_second;
uint32_t conf_samples_per_interval;
@ -474,7 +474,11 @@ struct switch_rtp {
payload_map_t *pmap_tail;
kalman_estimator_t *estimators[KALMAN_SYSTEM_MODELS];
cusum_kalman_detector_t *detectors[KALMAN_SYSTEM_MODELS];
int ice_adj;
switch_time_t last_adj;
switch_time_t adj_window;
uint32_t elapsed_stun;
uint32_t elapsed_media;
uint32_t elapsed_adj;
uint8_t has_rtp;
uint8_t has_rtcp;
uint8_t has_ice;
@ -540,9 +544,25 @@ static void switch_rtp_change_ice_dest(switch_rtp_t *rtp_session, switch_rtp_ice
{
int is_rtcp = ice == &rtp_session->rtcp_ice;
const char *err = "";
int i;
uint8_t ice_cand_found_idx = 0;
for (i = 0; i < ice->ice_params->cand_idx[ice->proto]; i++) {
if (!strcmp(host, ice->ice_params->cands[i][ice->proto].con_addr) && port == ice->ice_params->cands[i][ice->proto].con_port) {
ice_cand_found_idx = i;
}
}
if (!ice_cand_found_idx) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "ICE candidate [%s:%d] replaced with [%s:%d]\n",
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, host, port);
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr = switch_core_strdup(rtp_session->pool, host);
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port = port;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "ICE chosen candidate [%s:%d] set to idx [%d]\n", host, port, ice_cand_found_idx);
ice->ice_params->chosen[ice->proto] = ice_cand_found_idx;
}
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr = switch_core_strdup(rtp_session->pool, host);
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port = port;
ice->missed_count = 0;
if (is_rtcp) {
@ -796,7 +816,41 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
rtp_msg_t *send_msg, void *data, uint32_t datalen, switch_payload_t payload, uint32_t timestamp, switch_frame_flag_t *flags);
static switch_status_t ice_out(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice)
#define MEDIA_TOO_LONG 2000
#define STUN_TOO_LONG 20000
#define ADJ_TOO_LONG 1000
static void calc_elapsed(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice)
{
switch_time_t ref_point;
switch_time_t now;
now = switch_micro_time_now();
if (ice->last_ok && (!rtp_session->dtls || rtp_session->dtls->state == DS_READY)) {
ref_point = ice->last_ok;
} else {
ref_point = rtp_session->first_stun;
}
if (!ref_point) ref_point = now;
rtp_session->elapsed_stun = (unsigned int) ((now - ref_point) / 1000);
if (rtp_session->last_media) {
rtp_session->elapsed_media = (unsigned int) ((now - rtp_session->last_media) / 1000);
} else {
rtp_session->elapsed_media = MEDIA_TOO_LONG + 1;
}
if (rtp_session->last_adj) {
rtp_session->elapsed_adj = (unsigned int) ((now - rtp_session->last_adj) / 1000);
} else {
rtp_session->elapsed_adj = ADJ_TOO_LONG + 1;
}
}
static switch_status_t ice_out(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, switch_bool_t force)
{
uint8_t buf[256] = { 0 };
switch_stun_packet_t *packet;
@ -812,7 +866,7 @@ static switch_status_t ice_out(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice)
return SWITCH_STATUS_BREAK;
}
if (ice->next_run && ice->next_run > now) {
if (!force && ice->next_run && ice->next_run >= now) {
return SWITCH_STATUS_BREAK;
}
@ -907,8 +961,19 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
int ok = 1;
uint32_t *pri = NULL;
int is_rtcp = ice == &rtp_session->rtcp_ice;
uint32_t elapsed;
switch_time_t ref_point;
switch_channel_t *channel;
int i;
switch_sockaddr_t *from_addr = rtp_session->from_addr;
const char *from_host = NULL;
switch_port_t from_port = 0;
char faddr_buf[80] = "";
if (is_rtcp) {
from_addr = rtp_session->rtcp_from_addr;
}
from_host = switch_get_addr(faddr_buf, sizeof(faddr_buf), from_addr);
from_port = switch_sockaddr_get_port(from_addr);
//if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
// switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF OK %s CALL\n", rtp_type(rtp_session));
@ -931,6 +996,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
cpylen = sizeof(buf);
}
channel = switch_core_session_get_channel(rtp_session->session);
memcpy(buf, data, cpylen);
packet = switch_stun_packet_parse(buf, (uint32_t)cpylen);
@ -946,14 +1012,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
rtp_session->first_stun = rtp_session->last_stun;
}
if (ice->last_ok && (!rtp_session->dtls || rtp_session->dtls->state == DS_READY)) {
ref_point = ice->last_ok;
} else {
ref_point = rtp_session->first_stun;
}
elapsed = (unsigned int) ((switch_micro_time_now() - ref_point) / 1000);
calc_elapsed(rtp_session, ice);
end_buf = buf + ((sizeof(buf) > packet->header.length) ? packet->header.length : sizeof(buf));
@ -968,6 +1027,12 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
case SWITCH_STUN_ATTR_USE_CAND:
{
ice->rready = 1;
for (i = 0; i < ice->ice_params->cand_idx[ice->proto]; i++) {
if (!strcmp(ice->ice_params->cands[i][ice->proto].con_addr, from_host) && ice->ice_params->cands[i][ice->proto].con_port == from_port) {
ice->ice_params->cands[i][ice->proto].use_candidate = 1;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG6, "Got USE-CANDIDATE on %s:%d\n", ice->ice_params->cands[i][ice->proto].con_addr, ice->ice_params->cands[i][ice->proto].con_port);
}
}
}
break;
case SWITCH_STUN_ATTR_ERROR_CODE:
@ -1048,18 +1113,33 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
if (packet->header.type == SWITCH_STUN_BINDING_RESPONSE) {
ok = 1;
if (!ice->rready) {
if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) {
rtp_session->ice.rready = 1;
rtp_session->rtcp_ice.rready = 1;
} else {
ice->rready = 1;
}
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
switch_core_session_video_reinit(rtp_session->session);
if (rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) {
rtp_session->ice.rready = 1;
rtp_session->rtcp_ice.rready = 1;
} else {
ice->rready = 1;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG6, "Received STUN Binding Response from %s\n", from_host);
if (ice->ice_params) {
for (i = 0; i < ice->ice_params->cand_idx[ice->proto]; i++) {
if (!strcmp(ice->ice_params->cands[i][ice->proto].con_addr, from_host) && ice->ice_params->cands[i][ice->proto].con_port == from_port) {
ice->ice_params->cands[i][ice->proto].responsive = 1;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "Marked ICE candidate %s:%d as responsive\n", ice->ice_params->cands[i][ice->proto].con_addr, ice->ice_params->cands[i][ice->proto].con_port);
if (!strcmp(ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, from_host) && ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port == from_port) {
ice->cand_responsive = 1;
ice->initializing = 0;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "Chosen ICE candidate %s:%d is responsive\n", ice->ice_params->cands[i][ice->proto].con_addr, ice->ice_params->cands[i][ice->proto].con_port);
}
}
}
}
if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
switch_core_session_video_reinit(rtp_session->session);
}
}
if (!ok && ice == &rtp_session->ice && rtp_session->rtcp_ice.ice_params && pri &&
@ -1084,7 +1164,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
switch_port_t port = 0;
char *host = NULL;
if (elapsed > 20000 && pri) {
if (rtp_session->elapsed_stun > STUN_TOO_LONG && pri) {
int i, j;
uint32_t old;
//const char *tx_host;
@ -1176,6 +1256,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "missed too many: %d, looking for new ICE dest.\n",
ice->missed_count);
ice->rready = 0;
ice->cand_responsive = 0;
ok = 1;
}
@ -1185,9 +1266,8 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
//}
if (ok) {
const char *host = NULL, *host2 = NULL;
switch_port_t port = 0, port2 = 0;
char buf[80] = "";
const char *host2 = NULL;
switch_port_t port2 = 0;
char buf2[80] = "";
if (packet->header.type == SWITCH_STUN_BINDING_REQUEST) {
@ -1196,16 +1276,13 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
const char *remote_ip;
switch_size_t bytes;
char ipbuf[50];
switch_sockaddr_t *from_addr = rtp_session->from_addr;
switch_socket_t *sock_output = rtp_session->sock_output;
uint8_t do_adj = 0;
switch_time_t now = switch_micro_time_now();
int cmp = 0;
int cur_idx = -1;//, is_relay = 0;
int i;
int cur_idx = -1, is_relay = 0, is_responsive = 0, use_candidate = 0;
if (is_rtcp) {
from_addr = rtp_session->rtcp_from_addr;
sock_output = rtp_session->rtcp_sock_output;
}
@ -1231,58 +1308,123 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
bytes = switch_stun_packet_length(rpacket);
host = switch_get_addr(buf, sizeof(buf), from_addr);
port = switch_sockaddr_get_port(from_addr);
host2 = switch_get_addr(buf2, sizeof(buf2), ice->addr);
port2 = switch_sockaddr_get_port(ice->addr);
cmp = switch_cmp_addr(from_addr, ice->addr, SWITCH_FALSE);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG2,
"STUN from %s:%d %s\n", host, port, cmp ? "EXPECTED" : "IGNORED");
for (i = 0; i < ice->ice_params->cand_idx[ice->proto]; i++) {
if (!strcmp(ice->ice_params->cands[i][ice->proto].con_addr, from_host) && ice->ice_params->cands[i][ice->proto].con_port == from_port) {
if (!strcasecmp(ice->ice_params->cands[i][ice->proto].cand_type, "relay")) {
is_relay = 1;
}
if (ice->init && !cmp && switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE)) {
do_adj++;
rtp_session->ice_adj++;
rtp_session->wrong_addrs = 0;
ice->init = 0;
}
if (cmp) {
ice->last_ok = now;
rtp_session->wrong_addrs = 0;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG10, "ICE %d dt:%d i:%d i2:%d w:%d cmp:%d adj:%d\n", elapsed, (rtp_session->dtls && rtp_session->dtls->state != DS_READY), !ice->ready, !ice->rready, rtp_session->wrong_addrs, switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE), rtp_session->ice_adj);
if (ice->ice_params->cands[i][ice->proto].responsive) {
is_responsive = 1;
}
if ((rtp_session->dtls && rtp_session->dtls->state != DS_READY) ||
((!ice->ready || !ice->rready) && (rtp_session->wrong_addrs > 2 || switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE)) &&
rtp_session->ice_adj < 10)) {
do_adj++;
rtp_session->ice_adj++;
rtp_session->wrong_addrs = 0;
} else if (rtp_session->wrong_addrs > 10 || elapsed >= 5000) {
do_adj++;
}
if (!do_adj) {
rtp_session->wrong_addrs++;
}
for (i = 0; i < ice->ice_params->cand_idx[ice->proto]; i++) {
if (!strcmp(ice->ice_params->cands[i][ice->proto].con_addr, host)) {
cur_idx = i;
//if (!strcasecmp(ice->ice_params->cands[i][ice->proto].cand_type, "relay")) {
// is_relay = 1;
//}
if (ice->ice_params->cands[i][ice->proto].use_candidate) {
use_candidate = 1;
}
}
if (ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type &&
!strcasecmp(ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type, "relay")) {
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5,
"%s %s STUN from %s:%d %s is_relay: %d is_responsive: %d use_candidate: %d ready: %d, rready: %d\n", switch_channel_get_name(channel), rtp_type(rtp_session), from_host, from_port, cmp ? "EXPECTED" : "IGNORED",
is_relay, is_responsive, use_candidate, ice->ready, ice->rready);
if (ice->initializing && !cmp) {
if (!rtp_session->adj_window && (!ice->ready || !ice->rready || (!rtp_session->dtls || rtp_session->dtls->state != DS_READY))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE set ADJUST window to 10 seconds on binding request from %s:%d (is_relay: %d, is_responsivie: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n",
switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", from_host, from_port, is_relay, is_responsive, use_candidate,
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type);
rtp_session->adj_window = now + 10000000;
}
if (rtp_session->adj_window) {
if (rtp_session->adj_window > now) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE check: %d >= 3000 or window closed and not from relay on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n",
switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", rtp_session->elapsed_stun, from_host, from_port, is_relay, is_responsive, use_candidate,
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type);
if (!is_relay && (rtp_session->elapsed_stun >= 3000 || rtp_session->adj_window == (now + 10000000))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE ADJUST HIT 1 on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n",
switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", from_host, from_port, is_relay, is_responsive, use_candidate,
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type);
do_adj++;
rtp_session->last_adj = now;
}
} else {
rtp_session->adj_window = 0;
}
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE CHECK SAME IP DIFFT PORT %d %d on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n",
switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp",ice->initializing, switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE), from_host, from_port, is_relay, is_responsive, use_candidate,
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type);
if (!do_adj && (switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE) || use_candidate)) {
do_adj++;
rtp_session->last_adj = now;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE ADJUST HIT 2 on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n",
switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", from_host, from_port, is_relay, is_responsive, use_candidate,
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type);
}
}
if (cmp) {
ice->last_ok = now;
} else if (!do_adj) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "ICE %d/%d dt:%d i:%d i2:%d cmp:%d\n", rtp_session->elapsed_stun, rtp_session->elapsed_media, (rtp_session->dtls && rtp_session->dtls->state != DS_READY), !ice->ready, !ice->rready, switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE ADJUST ELAPSED vs 1000 %d on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n",
switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp" ,rtp_session->elapsed_adj, from_host, from_port, is_relay, is_responsive, use_candidate,
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type);
if (rtp_session->elapsed_adj > 1000) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE IF DTLS NOT READY or %d >= 3000 or media too long %d or stun too long %d on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n",
switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", rtp_session->elapsed_stun, rtp_session->elapsed_media >= MEDIA_TOO_LONG,
rtp_session->elapsed_stun >= STUN_TOO_LONG, from_host, from_port, is_relay, is_responsive, use_candidate,
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type);
if (!is_relay && ((rtp_session->dtls && rtp_session->dtls->state != DS_READY) ||
((!ice->ready || !ice->rready) && (rtp_session->elapsed_stun >= 3000 || switch_cmp_addr(from_addr, ice->addr, SWITCH_TRUE))))) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE ADJUST HIT 3 on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n",
switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", from_host, from_port, is_relay, is_responsive, use_candidate,
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type);
do_adj++;
rtp_session->last_adj = now;
} else if (is_relay && ice->initializing && rtp_session->elapsed_stun >= 1000) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE ADJUST HIT 4 (FLIP TO TURN) on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n",
switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", from_host, from_port, is_relay, is_responsive, use_candidate,
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type);
do_adj++;
rtp_session->last_adj = now;
} else if ((ice->initializing && rtp_session->elapsed_stun >= 3000) ||
(rtp_session->elapsed_media >= MEDIA_TOO_LONG || rtp_session->elapsed_stun >= STUN_TOO_LONG)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "%s %s %s ICE ADJUST HIT 5 on binding request from %s:%d (is_relay: %d, is_responsive: %d, use_candidate: %d) Current cand: %s:%d typ: %s\n",
switch_channel_get_name(channel), rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp", from_host, from_port, is_relay, is_responsive, use_candidate,
ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_addr, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].con_port, ice->ice_params->cands[ice->ice_params->chosen[ice->proto]][ice->proto].cand_type);
do_adj++;
rtp_session->last_adj = now;
}
for (i = 0; i < ice->ice_params->cand_idx[ice->proto]; i++) {
if (!strcmp(ice->ice_params->cands[i][ice->proto].con_addr, from_host)) {
cur_idx = i;
}
}
}
}
if ((ice->type & ICE_VANILLA) && ice->ice_params && do_adj) {
ice->missed_count = 0;
ice->rready = 1;
@ -1294,15 +1436,29 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_NOTICE,
"Auto Changing %s stun/%s/dtls port from %s:%u to %s:%u idx:%d\n", rtp_type(rtp_session), is_rtcp ? "rtcp" : "rtp",
host2, port2,
host, port, cur_idx);
from_host, from_port, cur_idx);
switch_rtp_change_ice_dest(rtp_session, ice, from_host, from_port);
ice->cand_responsive = is_responsive;
if (ice->cand_responsive) {
ice->initializing = 0;
}
switch_rtp_change_ice_dest(rtp_session, ice, host, port);
ice->last_ok = now;
rtp_session->wrong_addrs = 0;
}
//if (cmp) {
switch_socket_sendto(sock_output, from_addr, 0, (void *) rpacket, &bytes);
//}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG6, "Send STUN Binding Response to %s:%u\n", from_host, from_port);
if (ice->initializing && !is_responsive) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "Send STUN Binding Request on ICE candidate still unresponsive to %s:%u\n", from_host, from_port);
if (ice_out(rtp_session, ice, SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "Error sending STUN Binding Request on ICE candidate still unresponsive to %s:%u\n", from_host, from_port);
}
}
}
} else if (packet->header.type == SWITCH_STUN_BINDING_ERROR_RESPONSE) {
@ -2358,7 +2514,7 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
}
if (rtp_session->ice.ice_user) {
if (ice_out(rtp_session, &rtp_session->ice) == SWITCH_STATUS_GENERR) {
if (ice_out(rtp_session, &rtp_session->ice, SWITCH_FALSE) == SWITCH_STATUS_GENERR) {
ret = -1;
goto end;
}
@ -2366,7 +2522,7 @@ static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
if (!rtp_session->flags[SWITCH_RTP_FLAG_RTCP_MUX]) {
if (rtp_session->rtcp_ice.ice_user) {
if (ice_out(rtp_session, &rtp_session->rtcp_ice) == SWITCH_STATUS_GENERR) {
if (ice_out(rtp_session, &rtp_session->rtcp_ice, SWITCH_FALSE) == SWITCH_STATUS_GENERR) {
ret = -1;
goto end;
}
@ -2852,10 +3008,9 @@ SWITCH_DECLARE(void) switch_rtp_reset(switch_rtp_t *rtp_session)
memset(&rtp_session->ts_norm, 0, sizeof(rtp_session->ts_norm));
rtp_session->last_stun = rtp_session->first_stun = 0;
rtp_session->wrong_addrs = 0;
rtp_session->rtcp_sent_packets = 0;
rtp_session->rtcp_last_sent = 0;
rtp_session->ice_adj = 0;
rtp_session->last_adj = 0;
//switch_rtp_del_dtls(rtp_session, DTLS_TYPE_RTP|DTLS_TYPE_RTCP);
switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_PAUSE);
@ -2865,6 +3020,7 @@ SWITCH_DECLARE(void) switch_rtp_reset(switch_rtp_t *rtp_session)
if (rtp_session->ice.ready) {
switch_rtp_reset_vb(rtp_session);
rtp_session->ice.ready = rtp_session->ice.rready = 0;
rtp_session->ice.cand_responsive = 0;
}
}
@ -3210,13 +3366,31 @@ static int do_dtls(switch_rtp_t *rtp_session, switch_dtls_t *dtls)
int r = 0, ret = 0, len;
switch_size_t bytes;
unsigned char buf[MAX_DTLS_MTU] = "";
int ready = rtp_session->ice.ice_user ? (rtp_session->ice.rready && rtp_session->ice.ready) : 1;
uint8_t is_ice = rtp_session->ice.ice_user ? 1 : 0;
int ready = is_ice ? (rtp_session->ice.rready && rtp_session->ice.ready) : 1;
int pending;
if (!dtls->bytes && !ready) {
return 0;
}
if (is_ice && !(rtp_session->ice.type & ICE_LITE) && !rtp_session->ice.cand_responsive) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG6, "Got DTLS packet but candidate is not responsive\n");
return 0;
}
if (is_ice && !switch_cmp_addr(rtp_session->from_addr, rtp_session->ice.addr, SWITCH_TRUE)) {
char tmp_buf1[80] = "";
char tmp_buf2[80] = "";
const char *host_from = switch_get_addr(tmp_buf1, sizeof(tmp_buf1), rtp_session->from_addr);
const char *host_ice_cur_addr = switch_get_addr(tmp_buf2, sizeof(tmp_buf2), rtp_session->ice.addr);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG5, "Got DTLS packet from [%s] whilst current ICE negotiated address is [%s]. Ignored.\n", host_from, host_ice_cur_addr);
return 0;
}
if (dtls->bytes > 0 && dtls->data) {
ret = BIO_write(dtls->read_bio, dtls->data, (int)dtls->bytes);
if (ret <= 0) {
@ -4058,6 +4232,20 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
switch_channel_set_variable(channel, "rtp_has_crypto", "AES_CM_256_HMAC_SHA1_32");
}
break;
case AES_CM_192_HMAC_SHA1_80:
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(&policy->rtp);
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_80(&policy->rtcp);
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
switch_channel_set_variable(channel, "rtp_has_crypto", "AES_CM_192_HMAC_SHA1_80");
}
break;
case AES_CM_192_HMAC_SHA1_32:
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(&policy->rtp);
srtp_crypto_policy_set_aes_cm_192_hmac_sha1_32(&policy->rtcp);
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
switch_channel_set_variable(channel, "rtp_has_crypto", "AES_CM_192_HMAC_SHA1_32");
}
break;
case AES_CM_128_NULL_AUTH:
srtp_crypto_policy_set_aes_cm_128_null_auth(&policy->rtp);
srtp_crypto_policy_set_aes_cm_128_null_auth(&policy->rtcp);
@ -4067,6 +4255,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
}
break;
default:
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Missing crypto type!\n");
break;
}
@ -4324,8 +4513,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session
if (rtp_session->flags[SWITCH_RTP_FLAG_ENABLE_RTCP]) {
switch_sockaddr_create(&rtp_session->rtcp_from_addr, pool);
}
rtp_session->seq = (uint16_t) rand();
rtp_session->ssrc = (uint32_t) ((intptr_t) rtp_session + (uint32_t) switch_epoch_time_now(NULL));
rtp_session->ssrc = (uint32_t) ((intptr_t) rtp_session + (switch_time_t) switch_epoch_time_now(NULL));
#ifdef DEBUG_TS_ROLLOVER
rtp_session->last_write_ts = TS_ROLLOVER_START;
#endif
@ -4763,11 +4953,13 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio
switch_snprintf(user_ice, sizeof(user_ice), "%s:%s", rlogin, login);
switch_snprintf(luser_ice, sizeof(luser_ice), "%s%s", rlogin, login);
ice->ready = ice->rready = 0;
ice->cand_responsive = 0;
} else {
switch_snprintf(ice_user, sizeof(ice_user), "%s%s", login, rlogin);
switch_snprintf(user_ice, sizeof(user_ice), "%s%s", rlogin, login);
switch_snprintf(luser_ice, sizeof(luser_ice), "");
ice->ready = ice->rready = 1;
ice->cand_responsive = 0;
}
ice->ice_user = switch_core_strdup(rtp_session->pool, ice_user);
@ -4778,7 +4970,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio
ice->pass = "";
ice->rpass = "";
ice->next_run = switch_micro_time_now();
ice->init = 1;
ice->initializing = 1;
if (password) {
ice->pass = switch_core_strdup(rtp_session->pool, password);
@ -5724,7 +5916,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
/* version 2 probably rtp */
rtp_session->has_rtp = (rtp_session->recv_msg.header.version == 2);
if (rtp_session->media_timeout) {
if (rtp_session->media_timeout || rtp_session->ice.ice_user) {
rtp_session->last_media = switch_micro_time_now();
}
@ -8061,7 +8253,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
/* If the marker was set, and the timestamp seems to have started over - set a new SSRC, to indicate this is a new stream */
if (m && !switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_SEND) && (rtp_session->rtp_bugs & RTP_BUG_CHANGE_SSRC_ON_MARKER) &&
(rtp_session->flags[SWITCH_RTP_FLAG_RESET] || (rtp_session->ts <= rtp_session->last_write_ts && rtp_session->last_write_ts > 0))) {
switch_rtp_set_ssrc(rtp_session, (uint32_t) ((intptr_t) rtp_session + (uint32_t) switch_epoch_time_now(NULL)));
switch_rtp_set_ssrc(rtp_session, (uint32_t) ((intptr_t) rtp_session + (switch_time_t) switch_epoch_time_now(NULL)));
}
if (!switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO) && !switch_rtp_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL)) {

View File

@ -696,8 +696,11 @@ SWITCH_DECLARE(char *) switch_stun_host_lookup(const char *host, switch_memory_p
{
switch_sockaddr_t *addr = NULL;
char buf[30];
switch_status_t res;
res = switch_sockaddr_info_get(&addr, host, SWITCH_UNSPEC, 0, 0, pool);
(void)res;
switch_sockaddr_info_get(&addr, host, SWITCH_UNSPEC, 0, 0, pool);
return switch_core_strdup(pool, switch_str_nil(switch_get_addr(buf, sizeof(buf), addr)));
}
@ -720,6 +723,7 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip,
int funny = 0;
int size = sizeof(buf);
int xlen = sizeof(switch_stun_packet_header_t);
switch_status_t res;
switch_assert(err);
@ -729,25 +733,30 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip,
*err = "Success";
switch_sockaddr_info_get(&from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool);
res = switch_sockaddr_info_get(&from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool);
(void)res;
if (switch_sockaddr_info_get(&local_addr, *ip, SWITCH_UNSPEC, *port, 0, pool) != SWITCH_STATUS_SUCCESS) {
*err = "Local Address Error!";
return SWITCH_STATUS_FALSE;
}
if (switch_sockaddr_info_get(&remote_addr, stunip, SWITCH_UNSPEC, stunport, 0, pool) != SWITCH_STATUS_SUCCESS) {
*err = "Remote Address Error!";
return SWITCH_STATUS_FALSE;
}
if (switch_socket_create(&sock, AF_INET, SOCK_DGRAM, 0, pool) != SWITCH_STATUS_SUCCESS) {
*err = "Socket Error!";
return SWITCH_STATUS_FALSE;
}
if (switch_socket_bind(sock, local_addr) != SWITCH_STATUS_SUCCESS) {
*err = "Bind Error!";
return SWITCH_STATUS_FALSE;
}
@ -779,7 +788,6 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip,
*ip = NULL;
*port = 0;
for (;;) {
bytes = sizeof(buf);
if (switch_socket_recvfrom(from_addr, sock, 0, (char *) &buf, &bytes) == SWITCH_STATUS_SUCCESS && bytes > 0) {
@ -790,10 +798,12 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip,
*err = "Timeout";
switch_socket_shutdown(sock, SWITCH_SHUTDOWN_READWRITE);
switch_socket_close(sock);
return SWITCH_STATUS_TIMEOUT;
}
switch_cond_next();
}
switch_socket_close(sock);
if (funny) {
@ -803,14 +813,15 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip,
packet = switch_stun_packet_parse(start, size);
if (!packet) {
*err = "Invalid STUN/ICE packet";
return SWITCH_STATUS_FALSE;
}
end_buf = buf + ((sizeof(buf) > packet->header.length) ? packet->header.length : sizeof(buf));
switch_stun_packet_first_attribute(packet, attr);
switch_assert(attr);
do {
switch (attr->type) {
case SWITCH_STUN_ATTR_MAPPED_ADDRESS:
@ -818,6 +829,7 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip,
switch_stun_ip_t *tmp = (switch_stun_ip_t *) attr->value;
tmp->address ^= ntohl(0xabcdabcd);
}
switch_stun_packet_attribute_get_mapped_address(attr, rip, sizeof(rip), &rport);
break;
case SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS:
@ -831,12 +843,15 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip,
if (!switch_stun_packet_next_attribute(attr, end_buf)) {
break;
}
xlen += 4 + switch_stun_attribute_padded_length(attr);
} while (xlen <= packet->header.length);
if (packet->header.type == SWITCH_STUN_BINDING_RESPONSE) {
*ip = switch_core_strdup(pool, rip);
*port = rport;
return SWITCH_STATUS_SUCCESS;
} else {
*err = "Invalid Reply";

View File

@ -747,7 +747,7 @@ SWITCH_DECLARE(int) switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask,
ip_t *maskv = mask;
ip_t *ipv = ip;
switch_copy_string(host, string, sizeof(host)-1);
switch_copy_string(host, string, sizeof(host) - 1);
bit_str = strchr(host, '/');
if (!bit_str) {
@ -758,22 +758,20 @@ SWITCH_DECLARE(int) switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask,
bits = atoi(bit_str);
ipv6 = strchr(string, ':');
if (ipv6) {
int i,n;
int32_t i, n;
uint32_t k;
if (bits < 0 || bits > 128) {
return -2;
}
bits = atoi(bit_str);
switch_inet_pton(AF_INET6, host, (unsigned char *)ip);
for (n=bits,i=0 ;i < 16; i++){
if (n >= 8) {
maskv->v6.s6_addr[i] = 0xFF;
n -= 8;
} else if (n < 8) {
maskv->v6.s6_addr[i] = 0xFF & ~(0xFF >> n);
n -= n;
} else if (n == 0) {
maskv->v6.s6_addr[i] = 0x00;
}
for (n = bits, i = 0; i < 16; i++) {
k = (n > 8) ? 8 : n;
maskv->v6.s6_addr[i] = 0xFF & ~(0xFF >> k); /* k = 0 gives 0x00, k = 8 gives 0xFF */
n -= k;
}
} else {
if (bits < 0 || bits > 32) {
@ -786,6 +784,7 @@ SWITCH_DECLARE(int) switch_parse_cidr(const char *string, ip_t *ip, ip_t *mask,
maskv->v4 = 0xFFFFFFFF & ~(0xFFFFFFFF >> bits);
}
*bitp = bits;
return 0;
@ -1161,7 +1160,7 @@ SWITCH_DECLARE(switch_bool_t) switch_simple_email(const char *to,
switch_safe_free(dupfile);
}
switch_snprintf(filename, 80, "%s%smail.%d%04x", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, (int) switch_epoch_time_now(NULL), rand() & 0xffff);
switch_snprintf(filename, 80, "%s%smail.%d%04x", SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, (int)(switch_time_t) switch_epoch_time_now(NULL), rand() & 0xffff);
if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644)) > -1) {
if (file) {

View File

@ -1238,7 +1238,7 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *
if (context->last_received_seq && context->last_received_seq + 1 != frame->seq) {
switch_log_printf(SWITCH_CHANNEL_LOG, VPX_SWITCH_LOG_LEVEL, "Packet loss detected last=%d got=%d lost=%d\n", context->last_received_seq, frame->seq, frame->seq - context->last_received_seq);
if (is_keyframe && context->vpx_packet_buffer) switch_buffer_zero(context->vpx_packet_buffer);
if (is_keyframe) switch_buffer_zero(context->vpx_packet_buffer);
}
context->last_received_seq = frame->seq;

View File

@ -1726,6 +1726,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_file(const char *file)
if ( rename(new_file_tmp,new_file) ) {
goto done;
}
if ((fd = open(new_file, O_RDONLY, 0)) > -1) {
if ((xml = switch_xml_parse_fd(fd))) {
if (strcmp(abs, SWITCH_GLOBAL_filenames.conf_name)) {
@ -1733,8 +1734,8 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_file(const char *file)
new_file = NULL;
}
}
close(fd);
fd = -1;
}
}
@ -1747,10 +1748,6 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_parse_file(const char *file)
write_fd = NULL;
}
if (fd > -1) {
close(fd);
}
switch_safe_free(new_file_tmp);
switch_safe_free(new_file);
@ -2272,7 +2269,7 @@ SWITCH_DECLARE(switch_status_t) switch_xml_locate_user(const char *key,
switch_event_destroy(&my_params);
}
if (status != SWITCH_STATUS_SUCCESS && root && *root) {
if (status != SWITCH_STATUS_SUCCESS && *root) {
switch_xml_free(*root);
*root = NULL;
*domain = NULL;

View File

@ -53,6 +53,66 @@ FST_CORE_BEGIN("./conf")
}
FST_TEARDOWN_END()
FST_TEST_BEGIN(test_switch_parse_cidr_v6)
{
ip_t ip, mask;
uint32_t bits;
fst_check(!switch_parse_cidr("fe80::/10", &ip, &mask, &bits));
fst_check_int_equals(bits, 10);
fst_check_int_equals(ip.v6.s6_addr[0], 0xfe);
fst_check_int_equals(ip.v6.s6_addr[1], 0x80);
fst_check_int_equals(ip.v6.s6_addr[2], 0);
fst_check_int_equals(mask.v6.s6_addr[0], 0xff);
fst_check_int_equals(mask.v6.s6_addr[1], 0xc0);
fst_check_int_equals(mask.v6.s6_addr[2], 0);
fst_check(!switch_parse_cidr("::/0", &ip, &mask, &bits));
fst_check_int_equals(bits, 0);
fst_check_int_equals(ip.v6.s6_addr[0], 0);
fst_check_int_equals(ip.v6.s6_addr[1], 0);
fst_check_int_equals(ip.v6.s6_addr[2], 0);
fst_check_int_equals(mask.v6.s6_addr[0], 0);
fst_check_int_equals(mask.v6.s6_addr[1], 0);
fst_check_int_equals(mask.v6.s6_addr[2], 0);
fst_check(!switch_parse_cidr("::1/128", &ip, &mask, &bits));
fst_check_int_equals(bits, 128);
fst_check_int_equals(ip.v6.s6_addr[0], 0);
fst_check_int_equals(ip.v6.s6_addr[1], 0);
fst_check_int_equals(ip.v6.s6_addr[2], 0);
fst_check_int_equals(ip.v6.s6_addr[3], 0);
fst_check_int_equals(ip.v6.s6_addr[4], 0);
fst_check_int_equals(ip.v6.s6_addr[5], 0);
fst_check_int_equals(ip.v6.s6_addr[6], 0);
fst_check_int_equals(ip.v6.s6_addr[7], 0);
fst_check_int_equals(ip.v6.s6_addr[8], 0);
fst_check_int_equals(ip.v6.s6_addr[9], 0);
fst_check_int_equals(ip.v6.s6_addr[10], 0);
fst_check_int_equals(ip.v6.s6_addr[11], 0);
fst_check_int_equals(ip.v6.s6_addr[12], 0);
fst_check_int_equals(ip.v6.s6_addr[13], 0);
fst_check_int_equals(ip.v6.s6_addr[14], 0);
fst_check_int_equals(ip.v6.s6_addr[15], 1);
fst_check_int_equals(mask.v6.s6_addr[0], 0xff);
fst_check_int_equals(mask.v6.s6_addr[1], 0xff);
fst_check_int_equals(mask.v6.s6_addr[2], 0xff);
fst_check_int_equals(mask.v6.s6_addr[3], 0xff);
fst_check_int_equals(mask.v6.s6_addr[4], 0xff);
fst_check_int_equals(mask.v6.s6_addr[5], 0xff);
fst_check_int_equals(mask.v6.s6_addr[6], 0xff);
fst_check_int_equals(mask.v6.s6_addr[7], 0xff);
fst_check_int_equals(mask.v6.s6_addr[8], 0xff);
fst_check_int_equals(mask.v6.s6_addr[9], 0xff);
fst_check_int_equals(mask.v6.s6_addr[10], 0xff);
fst_check_int_equals(mask.v6.s6_addr[11], 0xff);
fst_check_int_equals(mask.v6.s6_addr[12], 0xff);
fst_check_int_equals(mask.v6.s6_addr[13], 0xff);
fst_check_int_equals(mask.v6.s6_addr[14], 0xff);
fst_check_int_equals(mask.v6.s6_addr[15], 0xff);
}
FST_TEST_END()
#if ENABLE_SNPRINTFV_TESTS
FST_TEST_BEGIN(test_snprintfv_1)
{