diff -wbBur ortp-0.20.0/build/win32native/ortp.def ortp.git/build/win32native/ortp.def --- ortp-0.20.0/build/win32native/ortp.def 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/build/win32native/ortp.def 2012-06-01 12:12:54.129997614 +0400 @@ -37,6 +37,8 @@ rtp_session_signal_connect rtp_session_signal_disconnect_by_callback rtp_session_set_ssrc + rtp_session_get_send_ssrc + rtp_session_get_recv_ssrc rtp_session_set_seq_number rtp_session_get_seq_number rtp_session_set_jitter_compensation @@ -221,9 +223,7 @@ srtp_transport_new ortp_srtp_init - rtp_session_get_send_ssrc ortp_srtp_create_configure_session - rtp_session_get_send_ssrc ortp_srtp_supported rtp_session_pick_with_cseq rtp_session_enable_network_simulation diff -wbBur ortp-0.20.0/configure.ac ortp.git/configure.ac --- ortp-0.20.0/configure.ac 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/configure.ac 2012-06-01 12:12:54.133330948 +0400 @@ -31,6 +31,7 @@ AM_INIT_AUTOMAKE([tar-ustar]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],) AC_CONFIG_HEADERS(ortp-config.h) +AC_CONFIG_MACRO_DIR([m4]) AC_DEFINE_UNQUOTED(ORTP_MAJOR_VERSION,$ORTP_MAJOR_VERSION, [major version]) AC_DEFINE_UNQUOTED(ORTP_MINOR_VERSION,$ORTP_MINOR_VERSION, [minor version]) AC_DEFINE_UNQUOTED(ORTP_MICRO_VERSION,$ORTP_MICRO_VERSION, [micro version]) @@ -69,6 +70,18 @@ ORTP_DEFS="$ORTP_DEFS -DORTP_INET6" fi +dnl enable timestamp support +AC_ARG_ENABLE(ntp-timestamp, + [ --enable-ntp-timestamp Turn on NTP timestamping on received packet], + [case "${enableval}" in + yes) ntptimestamp=true;; + no) ntptimestamp=false;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-ntp-timestamp) ;; + esac],[ntptimestamp=false]) +if test x$ntptimestamp = xtrue ; then + ORTP_DEFS="$ORTP_DEFS -DORTP_TIMESTAMP" +fi + AC_ARG_ENABLE(mode64bit, [ --enable-mode64bit=[yes/no] produce a 64-bit library. [default=no]], [case "${enableval}" in @@ -156,14 +169,13 @@ AC_ARG_WITH(thread-stack-size, AC_HELP_STRING([--with-thread-stack-size=SIZE-IN-BYTES],[Set thread stack size [[default=os-default]]]), [thread_stack_size=$withval], [thread_stack_size=0]) -AC_DEFINE_UNQUOTED(ORTP_DEFAULT_THREAD_STACK_SIZE, $thread_stack_size, [Default thread stack size (0 = let operating system decide)]) +AC_DEFINE_UNQUOTED(ORTP_DEFAULT_THREAD_STACK_SIZE, $thread_stack_size, [Default thread stack size (0 = let uperating system decide)]) dnl check for libsrtp support (secure rtp) AC_ARG_WITH( srtp, - [ --with-srtp Set prefix where libsrtp can be found or "none" to disable (ex:/usr or /usr/local)[default=/usr] ], - [ srtp_prefix=${withval}],[ srtp_prefix=/usr ]) - + AC_HELP_STRING([--with-srtp],[Set prefix where libsrtp can be found or "none" to disable (ex:/usr or /usr/local) [[default=/usr]]]), + [srtp_prefix=$withval], [srtp_prefix=/usr]) if test "${srtp_prefix}" != "none" ; then if test "${srtp_prefix}" != "/usr" || test "$mingw_found" = "yes" ; then SRTP_CFLAGS="-I${srtp_prefix}/include -I${srtp_prefix}/include/srtp" @@ -183,6 +195,7 @@ LDFLAGS="$LDFLAGS $SRTP_LIBS" LIBS_save=$LIBS AC_CHECK_LIB(srtp,srtp_init,have_srtp_lib=yes) + AC_CHECK_LIB(srtp,srtp_shutdown,[AC_DEFINE([HAVE_SRTP_SHUTDOWN],1,[Defined when srtp_shutdown() exists.])]) LDFLAGS=$LDFLAGS_save LIBS=$LIBS_save diff -wbBur ortp-0.20.0/include/ortp/ortp.h ortp.git/include/ortp/ortp.h --- ortp-0.20.0/include/ortp/ortp.h 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/include/ortp/ortp.h 2012-06-01 12:12:54.133330948 +0400 @@ -87,7 +87,8 @@ ORTP_WARNING=1<<2, ORTP_ERROR=1<<3, ORTP_FATAL=1<<4, - ORTP_LOGLEV_END=1<<5 + ORTP_TRACE=1<<5, + ORTP_LOGLEV_END=1<<6 } OrtpLogLevel; diff -wbBur ortp-0.20.0/include/ortp/rtp.h ortp.git/include/ortp/rtp.h --- ortp-0.20.0/include/ortp/rtp.h 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/include/ortp/rtp.h 2012-06-01 12:12:54.133330948 +0400 @@ -80,6 +80,7 @@ uint32_t max_jitter; /* biggest interarrival jitter (value in stream clock unit) */ uint64_t sum_jitter; /* sum of all interarrival jitter (value in stream clock unit) */ uint64_t max_jitter_ts; /* date (in ms since Epoch) of the biggest interarrival jitter */ + float jitter_buffer_size_ms; /* mean jitter buffer size in milliseconds.*/ } jitter_stats_t; #define RTP_TIMESTAMP_IS_NEWER_THAN(ts1,ts2) \ diff -wbBur ortp-0.20.0/include/ortp/rtpsession.h ortp.git/include/ortp/rtpsession.h --- ortp-0.20.0/include/ortp/rtpsession.h 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/include/ortp/rtpsession.h 2012-06-01 12:12:54.133330948 +0400 @@ -62,7 +62,7 @@ typedef struct _JitterControl { - int count; + unsigned int count; int jitt_comp; /* the user jitt_comp in miliseconds*/ int jitt_comp_ts; /* the jitt_comp converted in rtp time (same unit as timestamp) */ int adapt_jitt_comp_ts; @@ -73,6 +73,9 @@ float inter_jitter; /* interarrival jitter as defined in the RFC */ int corrective_step; int corrective_slide; + uint64_t cum_jitter_buffer_size; /*in timestamp units*/ + unsigned int cum_jitter_buffer_count; /*used for computation of jitter buffer size*/ + int clock_rate; bool_t adaptive; bool_t enabled; } JitterControl; @@ -266,6 +269,7 @@ int rtp_session_signal_disconnect_by_callback(RtpSession *session,const char *signal_name, RtpCallback cb); void rtp_session_set_ssrc(RtpSession *session, uint32_t ssrc); uint32_t rtp_session_get_send_ssrc(RtpSession* session); +uint32_t rtp_session_get_recv_ssrc(RtpSession *session); void rtp_session_set_seq_number(RtpSession *session, uint16_t seq); uint16_t rtp_session_get_seq_number(RtpSession *session); diff -wbBur ortp-0.20.0/include/ortp/str_utils.h ortp.git/include/ortp/str_utils.h --- ortp-0.20.0/include/ortp/str_utils.h 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/include/ortp/str_utils.h 2012-06-01 12:12:54.133330948 +0400 @@ -22,7 +22,9 @@ #include - +#if defined(ORTP_TIMESTAMP) +#include +#endif typedef struct msgb { @@ -34,8 +36,13 @@ unsigned char *b_wptr; uint32_t reserved1; uint32_t reserved2; +#if defined(ORTP_TIMESTAMP) + struct timeval timestamp; +#endif } mblk_t; + + typedef struct datab { unsigned char *db_base; @@ -72,6 +79,8 @@ void mblk_init(mblk_t *mp); +void mblk_meta_copy(const mblk_t *source, mblk_t *dest); + /* allocates a mblk_t, that points to a datab_t, that points to a buffer of size size. */ mblk_t *allocb(int size, int unused); #define BPRI_MED 0 diff -wbBur ortp-0.20.0/include/ortp/stun_udp.h ortp.git/include/ortp/stun_udp.h --- ortp-0.20.0/include/ortp/stun_udp.h 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/include/ortp/stun_udp.h 2012-06-01 12:12:54.133330948 +0400 @@ -40,12 +40,13 @@ #include +#if defined(WIN32) || defined(_WIN32_WCE) + #if !defined(_WIN32_WCE) #include #endif -#if defined(WIN32) || defined(_WIN32_WCE) -#define snprintf _snprintf + #include /* #include */ diff -wbBur ortp-0.20.0/INSTALL ortp.git/INSTALL --- ortp-0.20.0/INSTALL 2012-02-22 20:21:24.000000000 +0400 +++ ortp.git/INSTALL 2012-06-01 12:12:54.113330946 +0400 @@ -1,8 +1,8 @@ Installation Instructions ************************* -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, -2006, 2007, 2008, 2009 Free Software Foundation, Inc. +Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, +Inc. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright @@ -226,6 +226,11 @@ and if that doesn't work, install pre-built binaries of GCC for HP-UX. + HP-UX `make' updates targets which have the same time stamps as +their prerequisites, which makes it generally unusable when shipped +generated files such as `configure' are involved. Use GNU `make' +instead. + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot parse its `' header file. The option `-nodtk' can be used as a workaround. If GNU CC is not installed, it is therefore recommended diff -wbBur ortp-0.20.0/Makefile.am ortp.git/Makefile.am --- ortp-0.20.0/Makefile.am 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/Makefile.am 2012-06-01 12:12:54.113330946 +0400 @@ -1,5 +1,7 @@ # linphone/oRTP/Makefile.am -- +ACLOCAL_AMFLAGS = -I m4 + EXTRA_DIST = oRTP.prj ortp-config.h.in TODO pkg.list autogen.sh ortp.pc.in ortp.spec.in ortp.spec ortp.doxygen SUBDIRS=src build include diff -wbBur ortp-0.20.0/ortp.spec.in ortp.git/ortp.spec.in --- ortp-0.20.0/ortp.spec.in 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/ortp.spec.in 2012-06-01 12:12:54.133330948 +0400 @@ -12,7 +12,7 @@ Summary: Real-time Transport Protocol Stack Name: ortp Version: @ORTP_PKGCONFIG_VERSION@ -Release: 2 +Release: %(git describe --tags --abbrev=40 | sed -rn 's/^.*-([0-9]+)-g[a-z0-9]{40}$/\1/p' || echo '1')%{?dist} License: LGPL Group: Applications/Communications URL: http://linphone.org/ortp/ diff -wbBur ortp-0.20.0/src/jitterctl.c ortp.git/src/jitterctl.c --- ortp-0.20.0/src/jitterctl.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/jitterctl.c 2012-06-01 12:12:54.133330948 +0400 @@ -43,7 +43,10 @@ ctl->jitter=0; ctl->inter_jitter=0; ctl->slide=0; + ctl->cum_jitter_buffer_count=0; + ctl->cum_jitter_buffer_size=0; if (base_jiitt_time!=-1) ctl->jitt_comp = base_jiitt_time; + ctl->clock_rate=8000; /* convert in timestamp unit: */ if (payload!=NULL){ jitter_control_set_payload(ctl,payload); @@ -62,6 +65,7 @@ /*make correction by not less than 10ms */ ctl->corrective_step=(int) (0.01 * (float)pt->clock_rate); ctl->adapt_jitt_comp_ts=ctl->jitt_comp_ts; + ctl->clock_rate=pt->clock_rate; } @@ -85,6 +89,17 @@ } } +void jitter_control_update_size(JitterControl *ctl, queue_t *q){ + mblk_t *newest=qlast(q); + mblk_t *oldest=qbegin(q); + uint32_t newest_ts,oldest_ts; + if (newest==NULL) return; + newest_ts=rtp_get_timestamp(newest); + oldest_ts=rtp_get_timestamp(oldest); + ctl->cum_jitter_buffer_count++; + ctl->cum_jitter_buffer_size+=(uint32_t)(newest_ts-oldest_ts); +} + /* The algorithm computes two values: slide: an average of difference between the expected and the socket-received timestamp @@ -125,7 +140,15 @@ return ; } - +float jitter_control_compute_mean_size(JitterControl *ctl){ + if (ctl->cum_jitter_buffer_count!=0){ + double tmp=((double)ctl->cum_jitter_buffer_size)/(double)ctl->cum_jitter_buffer_count; + ctl->cum_jitter_buffer_size=0; + ctl->cum_jitter_buffer_count=0; + return 1000.0*(float)tmp/(float)ctl->clock_rate; + } + return 0; +} diff -wbBur ortp-0.20.0/src/jitterctl.h ortp.git/src/jitterctl.h --- ortp-0.20.0/src/jitterctl.h 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/jitterctl.h 2012-06-01 12:12:54.133330948 +0400 @@ -34,6 +34,8 @@ #define jitter_control_adaptive_enabled(ctl) ((ctl)->adaptive) void jitter_control_set_payload(JitterControl *ctl, PayloadType *pt); void jitter_control_update_corrective_slide(JitterControl *ctl); +void jitter_control_update_size(JitterControl *ctl, queue_t *q); +float jitter_control_compute_mean_size(JitterControl *ctl); static inline uint32_t jitter_control_get_compensated_timestamp(JitterControl *obj , uint32_t user_ts){ return (uint32_t)( (int64_t)user_ts+obj->slide-(int64_t)obj->adapt_jitt_comp_ts); diff -wbBur ortp-0.20.0/src/netsim.c ortp.git/src/netsim.c --- ortp-0.20.0/src/netsim.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/netsim.c 2012-06-01 12:12:54.133330948 +0400 @@ -109,9 +109,19 @@ return output; } +static mblk_t *simulate_loss_rate(RtpSession *session, mblk_t *input, int rate){ + if((rand() % 101) >= rate) { + return input; + } + return NULL; +} + mblk_t * rtp_session_network_simulate(RtpSession *session, mblk_t *input){ OrtpNetworkSimulatorCtx *sim=session->net_sim_ctx; mblk_t *om=NULL; + if (sim->params.loss_rate>0){ + om=simulate_loss_rate(session,input, sim->params.loss_rate); + } if (sim->params.max_bandwidth>0){ om=simulate_bandwidth_limit(session,input); } diff -wbBur ortp-0.20.0/src/ortp.c ortp.git/src/ortp.c --- ortp-0.20.0/src/ortp.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/ortp.c 2012-06-01 12:12:54.133330948 +0400 @@ -70,15 +70,16 @@ } #endif +static int ortp_initialized=0; + /** * Initialize the oRTP library. You should call this function first before using * oRTP API. **/ void ortp_init() { - static bool_t initialized=FALSE; - if (initialized) return; - initialized=TRUE; + if (ortp_initialized) return; + ortp_initialized++; #ifdef WIN32 win32_init_sockets(); @@ -131,11 +132,17 @@ **/ void ortp_exit() { + ortp_initialized--; + if (ortp_initialized==0){ if (__ortp_scheduler!=NULL) { rtp_scheduler_destroy(__ortp_scheduler); __ortp_scheduler=NULL; } +#ifdef HAVE_SRTP_SHUTDOWN + srtp_shutdown(); +#endif + } } RtpScheduler * ortp_get_scheduler() diff -wbBur ortp-0.20.0/src/ortp_srtp.c ortp.git/src/ortp_srtp.c --- ortp-0.20.0/src/ortp_srtp.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/ortp_srtp.c 2012-06-01 12:12:54.136664281 +0400 @@ -30,19 +30,20 @@ #undef PACKAGE_VERSION #include "ortp/ortp_srtp.h" +#include "rtpsession_priv.h" #ifdef HAVE_SRTP #include "ortp/b64.h" -#define SRTP_PAD_BYTES 64 /*?? */ +#define SRTP_PAD_BYTES (SRTP_MAX_TRAILER_LEN + 4) static int srtp_sendto(RtpTransport *t, mblk_t *m, int flags, const struct sockaddr *to, socklen_t tolen){ srtp_t srtp=(srtp_t)t->data; int slen; err_status_t err; /* enlarge the buffer for srtp to write its data */ - msgpullup(m,msgdsize(m)+SRTP_PAD_BYTES); - slen=m->b_wptr-m->b_rptr; + slen=msgdsize(m); + msgpullup(m,slen+SRTP_PAD_BYTES); err=srtp_protect(srtp,m->b_rptr,&slen); if (err==err_status_ok){ return sendto(t->session->rtp.socket,(void*)m->b_rptr,slen,flags,to,tolen); @@ -55,7 +56,7 @@ srtp_t srtp=(srtp_t)t->data; int err; int slen; - err=recvfrom(t->session->rtp.socket,(void*)m->b_wptr,m->b_datap->db_lim-m->b_datap->db_base,flags,from,fromlen); + err=rtp_session_rtp_recv_abstract(t->session->rtp.socket,m,flags,from,fromlen); if (err>0){ err_status_t srtp_err; /* keep NON-RTP data unencrypted */ @@ -85,9 +86,9 @@ srtp_t srtp=(srtp_t)t->data; int slen; err_status_t srtp_err; + slen=msgdsize(m); /* enlarge the buffer for srtp to write its data */ - msgpullup(m,msgdsize(m)+SRTP_PAD_BYTES); - slen=m->b_wptr-m->b_rptr; + msgpullup(m,slen+SRTP_PAD_BYTES); srtp_err=srtp_protect_rtcp(srtp,m->b_rptr,&slen); if (srtp_err==err_status_ok){ return sendto(t->session->rtcp.socket,(void*)m->b_rptr,slen,flags,to,tolen); @@ -100,7 +101,7 @@ srtp_t srtp=(srtp_t)t->data; int err; int slen; - err=recvfrom(t->session->rtcp.socket,(void*)m->b_wptr,m->b_datap->db_lim-m->b_datap->db_base,flags,from,fromlen); + err=rtp_session_rtp_recv_abstract(t->session->rtcp.socket,m,flags,from,fromlen); if (err>0){ err_status_t srtp_err; slen=err; @@ -214,10 +215,10 @@ policy->rtp.cipher_key_len); return FALSE; } - key = (uint8_t*) malloc(key_size); - if (b64_decode((const char*)b64_key, b64_key_length, key, key_size) != key_size) { + key = (uint8_t*) ortp_malloc0(key_size+2); /*srtp uses padding*/ + if (b64_decode(b64_key, b64_key_length, key, key_size) != key_size) { ortp_error("Error decoding key"); - free(key); + ortp_free(key); return FALSE; } @@ -228,11 +229,11 @@ err = ortp_srtp_add_stream(srtp, policy); if (err != err_status_ok) { ortp_error("Failed to add incoming stream to srtp session (%d)", err); - free(key); + ortp_free(key); return FALSE; } - free(key); + ortp_free(key); return TRUE; } diff -wbBur ortp-0.20.0/src/port.c ortp.git/src/port.c --- ortp-0.20.0/src/port.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/port.c 2012-06-01 12:12:54.136664281 +0400 @@ -411,6 +411,14 @@ } int ortp_server_pipe_close(ortp_socket_t spipe){ + struct sockaddr_un sa; + socklen_t len=sizeof(sa); + int err; + /*this is to retrieve the name of the pipe, in order to unlink the file*/ + err=getsockname(spipe,(struct sockaddr*)&sa,&len); + if (err==0){ + unlink(sa.sun_path); + }else ortp_error("getsockname(): %s",strerror(errno)); return close(spipe); } diff -wbBur ortp-0.20.0/src/rtcp.c ortp.git/src/rtcp.c --- ortp-0.20.0/src/rtcp.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/rtcp.c 2012-06-01 12:12:54.136664281 +0400 @@ -32,6 +32,7 @@ #include "ortp/rtcp.h" #include "utils.h" #include "rtpsession_priv.h" +#include "jitterctl.h" #define rtcp_bye_set_ssrc(b,pos,ssrc) (b)->ssrc[pos]=htonl(ssrc) #define rtcp_bye_get_ssrc(b,pos) ntohl((b)->ssrc[pos]) @@ -311,6 +312,8 @@ gettimeofday( &now, NULL ); session->rtp.jitter_stats.max_jitter_ts = ( now.tv_sec * 1000LL ) + ( now.tv_usec / 1000LL ); } + /* compute mean jitter buffer size */ + session->rtp.jitter_stats.jitter_buffer_size_ms=jitter_control_compute_mean_size(&session->rtp.jittctl); } diff -wbBur ortp-0.20.0/src/rtpparse.c ortp.git/src/rtpparse.c --- ortp-0.20.0/src/rtpparse.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/rtpparse.c 2012-06-01 12:12:54.136664281 +0400 @@ -23,7 +23,7 @@ #include "utils.h" #include "rtpsession_priv.h" -static void queue_packet(queue_t *q, int maxrqsz, mblk_t *mp, rtp_header_t *rtp, int *discarded) +static bool_t queue_packet(queue_t *q, int maxrqsz, mblk_t *mp, rtp_header_t *rtp, int *discarded) { mblk_t *tmp; int header_size; @@ -33,7 +33,7 @@ ortp_debug("Rtp packet contains no data."); (*discarded)++; freemsg(mp); - return; + return FALSE; } /* and then add the packet to the queue */ @@ -50,6 +50,7 @@ (*discarded)++; } } + return TRUE; } void rtp_session_rtp_parse(RtpSession *session, mblk_t *mp, uint32_t local_str_ts, struct sockaddr *addr, socklen_t addrlen) @@ -231,7 +232,8 @@ } } - queue_packet(&session->rtp.rq,session->rtp.max_rq_size,mp,rtp,&i); + if (queue_packet(&session->rtp.rq,session->rtp.max_rq_size,mp,rtp,&i)) + jitter_control_update_size(&session->rtp.jittctl,&session->rtp.rq); stats->discarded+=i; ortp_global_stats.discarded+=i; } diff -wbBur ortp-0.20.0/src/rtpsession.c ortp.git/src/rtpsession.c --- ortp-0.20.0/src/rtpsession.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/rtpsession.c 2012-06-01 12:12:54.136664281 +0400 @@ -620,13 +620,26 @@ session->snd.ssrc = ssrc; } - +/** + * Get the SSRC for the outgoing stream. + * + * @param session a rtp session. +**/ uint32_t rtp_session_get_send_ssrc (RtpSession* session) { return session->snd.ssrc; } +/** + * Get the SSRC for the incoming stream. + * + * If no packets have been received yet, 0 is returned. +**/ +uint32_t rtp_session_get_recv_ssrc(RtpSession *session){ + return session->rcv.ssrc; +} + void rtp_session_update_payload_type(RtpSession *session, int paytype){ /* check if we support this payload type */ diff -wbBur ortp-0.20.0/src/rtpsession_inet.c ortp.git/src/rtpsession_inet.c --- ortp-0.20.0/src/rtpsession_inet.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/rtpsession_inet.c 2012-06-01 12:12:54.136664281 +0400 @@ -86,6 +86,14 @@ ortp_warning ("Fail to set rtp address reusable: %s.", getSocketError()); } } +#if defined(ORTP_TIMESTAMP) + err = setsockopt (sock, SOL_SOCKET, SO_TIMESTAMP, + (SOCKET_OPTION_VALUE)&optval, sizeof (optval)); + if (err < 0) + { + ortp_warning ("Fail to set rtp timestamp: %s.",getSocketError()); + } +#endif *sock_family=res->ai_family; err = bind (sock, res->ai_addr, res->ai_addrlen); @@ -156,6 +164,14 @@ ortp_warning ("Fail to set rtp address reusable: %s.",getSocketError()); } } +#if defined(ORTP_TIMESTAMP) + err = setsockopt (sock, SOL_SOCKET, SO_TIMESTAMP, + (SOCKET_OPTION_VALUE)&optval, sizeof (optval)); + if (err < 0) + { + ortp_warning ("Fail to set rtp timestamp: %s.",getSocketError()); + } +#endif err = bind (sock, (struct sockaddr *) &saddr, @@ -954,8 +970,54 @@ return error; } -int -rtp_session_rtp_recv (RtpSession * session, uint32_t user_ts) +int rtp_session_rtp_recv_abstract(ortp_socket_t socket, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen) { + int bufsz = (int) (msg->b_datap->db_lim - msg->b_datap->db_base); +#ifndef _WIN32 + struct iovec iov; + struct msghdr msghdr; +#if defined(ORTP_TIMESTAMP) + struct cmsghdr *cmsghdr; + struct { + struct cmsghdr cm; + char control[512]; + } control; +#endif + memset(&msghdr, 0, sizeof(msghdr)); + memset(&iov, 0, sizeof(iov)); + iov.iov_base = msg->b_wptr; + iov.iov_len = bufsz; + if(from != NULL && fromlen != NULL) { + msghdr.msg_name = from; + msghdr.msg_namelen = *fromlen; + } + msghdr.msg_iov = &iov; + msghdr.msg_iovlen = 1; +#if defined(ORTP_TIMESTAMP) + msghdr.msg_control = &control; + msghdr.msg_controllen = sizeof(control); +#endif + + int ret = recvmsg(socket, &msghdr, flags); + if(fromlen != NULL) + *fromlen = msghdr.msg_namelen; +#if defined(ORTP_TIMESTAMP) + if(ret >= 0) { + for (cmsghdr = CMSG_FIRSTHDR(&msghdr); cmsghdr != NULL ; cmsghdr = CMSG_NXTHDR(&msghdr, cmsghdr)) { + if (cmsghdr->cmsg_level == SOL_SOCKET && cmsghdr->cmsg_type == SO_TIMESTAMP) { + memcpy(&msg->timestamp, (struct timeval *)CMSG_DATA(cmsghdr), sizeof(struct timeval)); + } + } + } +#endif + return ret; +#else + return recvfrom(socket, (char *)msg->b_wptr, bufsz, flags, from, fromlen); +#endif + + +} + +int rtp_session_rtp_recv (RtpSession * session, uint32_t user_ts) { int error; ortp_socket_t sockfd=session->rtp.socket; @@ -971,23 +1033,21 @@ while (1) { - int bufsz; bool_t sock_connected=!!(session->flags & RTP_SOCKET_CONNECTED); if (session->rtp.cached_mp==NULL) session->rtp.cached_mp = msgb_allocator_alloc(&session->allocator,session->recv_buf_size); mp=session->rtp.cached_mp; - bufsz=(int) (mp->b_datap->db_lim - mp->b_datap->db_base); if (sock_connected){ - error=recv(sockfd,(char*)mp->b_wptr,bufsz,0); - }else if (rtp_session_using_transport(session, rtp)) + error=rtp_session_rtp_recv_abstract(sockfd, mp, 0, NULL, NULL); + }else if (rtp_session_using_transport(session, rtp)) { error = (session->rtp.tr->t_recvfrom)(session->rtp.tr, mp, 0, (struct sockaddr *) &remaddr, &addrlen); - else error = recvfrom(sockfd, (char*)mp->b_wptr, - bufsz, 0, + } else { error = rtp_session_rtp_recv_abstract(sockfd, mp, 0, (struct sockaddr *) &remaddr, &addrlen); + } if (error > 0){ if (session->symmetric_rtp && !sock_connected){ if (session->use_connect){ @@ -1017,6 +1077,13 @@ if (session->on_network_error.count>0){ rtp_signal_table_emit3(&session->on_network_error,(long)"Error receiving RTP packet",INT_TO_POINTER(getSocketErrorCode())); }else ortp_warning("Error receiving RTP packet: %s, err num [%i],error [%i]",getSocketError(),errnum,error); +#ifdef __ios + /*hack for iOS and non-working socket because of background mode*/ + if (errnum==ENOTCONN){ + /*re-create new sockets */ + rtp_session_set_local_addr(session,session->rtp.sockfamily==AF_INET ? "0.0.0.0" : "::0",session->rtp.loc_port); + } +#endif }else{ /*EWOULDBLOCK errors or transports returning 0 are ignored.*/ if (session->net_sim_ctx){ @@ -1149,7 +1216,7 @@ mp=session->rtcp.cached_mp; if (sock_connected){ - error=recv(session->rtcp.socket,(char*)mp->b_wptr,RTCP_MAX_RECV_BUFSIZE,0); + error=rtp_session_rtp_recv_abstract(session->rtcp.socket, mp, 0, NULL, NULL); }else { addrlen=sizeof (remaddr); @@ -1158,8 +1225,7 @@ (struct sockaddr *) &remaddr, &addrlen); else - error=recvfrom (session->rtcp.socket,(char*) mp->b_wptr, - RTCP_MAX_RECV_BUFSIZE, 0, + error=rtp_session_rtp_recv_abstract (session->rtcp.socket,mp, 0, (struct sockaddr *) &remaddr, &addrlen); } diff -wbBur ortp-0.20.0/src/rtpsession_priv.h ortp.git/src/rtpsession_priv.h --- ortp-0.20.0/src/rtpsession_priv.h 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/rtpsession_priv.h 2012-06-01 12:12:54.136664281 +0400 @@ -41,6 +41,8 @@ #define rtp_session_using_transport(s, stream) (((s)->flags & RTP_SESSION_USING_TRANSPORT) && (s->stream.tr != 0)) +int rtp_session_rtp_recv_abstract(ortp_socket_t socket, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen); + void rtp_session_update_payload_type(RtpSession * session, int pt); void rtp_putq(queue_t *q, mblk_t *mp); mblk_t * rtp_getq(queue_t *q, uint32_t ts, int *rejected); diff -wbBur ortp-0.20.0/src/scheduler.c ortp.git/src/scheduler.c --- ortp-0.20.0/src/scheduler.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/scheduler.c 2012-06-01 12:12:54.136664281 +0400 @@ -116,7 +116,7 @@ /* processing all scheduled rtp sessions */ while (current!=NULL) { - ortp_debug("scheduler: processing session=0x%x.\n",current); + ortp_debug("scheduler: processing session=0x%p.\n",current); rtp_session_process(current,sched->time_,sched); current=current->next; } diff -wbBur ortp-0.20.0/src/str_utils.c ortp.git/src/str_utils.c --- ortp-0.20.0/src/str_utils.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/str_utils.c 2012-06-01 12:12:54.136664281 +0400 @@ -35,6 +35,17 @@ mp->b_rptr=mp->b_wptr=NULL; mp->reserved1=0; mp->reserved2=0; +#if defined(ORTP_TIMESTAMP) + memset(&(mp->timestamp), 0, sizeof(struct timeval)); +#endif +} + +void mblk_meta_copy(const mblk_t *source, mblk_t *dest) { + dest->reserved1 = source->reserved1; + dest->reserved2 = source->reserved2; +#if defined(ORTP_TIMESTAMP) + dest->timestamp = source->timestamp; +#endif } dblk_t *datab_alloc(int size){ @@ -129,8 +140,7 @@ datab_ref(mp->b_datap); newm=(mblk_t *) ortp_malloc(sizeof(mblk_t)); mblk_init(newm); - newm->reserved1=mp->reserved1; - newm->reserved2=mp->reserved2; + mblk_meta_copy(mp, newm); newm->b_datap=mp->b_datap; newm->b_rptr=mp->b_rptr; newm->b_wptr=mp->b_wptr; diff -wbBur ortp-0.20.0/src/stun.c ortp.git/src/stun.c --- ortp-0.20.0/src/stun.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/stun.c 2012-06-01 12:12:54.136664281 +0400 @@ -80,6 +80,11 @@ #if defined(WIN32) || defined(_WIN32_WCE) #include #include + +#ifndef snprintf +#define snprintf _snprintf +#endif + /* #include */ #include #include /*for isdigit() */ diff -wbBur ortp-0.20.0/src/zrtp.c ortp.git/src/zrtp.c --- ortp-0.20.0/src/zrtp.c 2012-02-22 20:19:51.000000000 +0400 +++ ortp.git/src/zrtp.c 2012-06-01 12:12:54.139997614 +0400 @@ -41,7 +41,7 @@ // ZRTP message is prefixed by RTP header #define ZRTP_MESSAGE_OFFSET 12 -#define SRTP_PAD_BYTES 64 /*?? */ +#define SRTP_PAD_BYTES (SRTP_MAX_TRAILER_LEN + 4) // 1234567890123456 static const char userAgentStr[] = "LINPHONE-ZRTPCPP"; // 16 chars max. @@ -407,7 +407,8 @@ err_status_t addStreamStatus; OrtpZrtpContext *userData = user_data(ctx); - ortp_message("ZRTP secrets for %s are ready", (part == ForSender) ? "sender" : "receiver"); + ortp_message("ZRTP secrets for %s are ready; auth tag len is %i", + (part == ForSender) ? "sender" : "receiver",secrets->srtpAuthTagLen); // Get authentication and cipher algorithms in srtp format if (secrets->authAlgorithm != zrtp_Sha1) { @@ -417,27 +418,31 @@ if (secrets->symEncAlgorithm != zrtp_Aes) { ortp_fatal("unsupported cipher algorithm by srtp"); } - memset(&policy,0,sizeof(policy)); - policy.ssrc.type=ssrc_specific; - crypto_policy_t cryptoPolicyRtp; - crypto_policy_set_from_profile_for_rtp(&cryptoPolicyRtp, srtp_profile_aes128_cm_sha1_32); - policy.rtp=cryptoPolicyRtp; - - crypto_policy_t cryptoPolicyRtcp; - crypto_policy_set_from_profile_for_rtcp(&cryptoPolicyRtcp, srtp_profile_aes128_cm_sha1_32); - policy.rtcp=cryptoPolicyRtcp; + /* + * Don't use crypto_policy_set_from_profile_for_rtp(), it is totally buggy. + */ + memset(&policy,0,sizeof(policy)); + if (secrets->srtpAuthTagLen == 32){ + crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtp); + crypto_policy_set_aes_cm_128_hmac_sha1_32(&policy.rtcp); + }else if (secrets->srtpAuthTagLen == 80){ + crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp); + crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp); + }else{ + ortp_fatal("unsupported auth tag len"); + } if (part == ForSender) { srtpCreateStatus=srtp_create(&userData->srtpSend, NULL); + policy.ssrc.type=ssrc_specific; policy.ssrc.value=userData->session->snd.ssrc; // us policy.key=key_with_salt(secrets, secrets->role); addStreamStatus=srtp_add_stream(userData->srtpSend, &policy); } else { //if (part == ForReceiver) srtpCreateStatus=srtp_create(&userData->srtpRecv, NULL); policy.ssrc.type = ssrc_any_inbound; /*we don't know the incoming ssrc will be */ - policy.ssrc.value=userData->session->rcv.ssrc; // peer int32_t peerRole=secrets->role == Initiator ? Responder : Initiator; policy.key=key_with_salt(secrets,peerRole); addStreamStatus=srtp_add_stream(userData->srtpRecv, &policy); @@ -622,11 +627,10 @@ size=msgdsize(m); return sendto(socket,(void*)m->b_rptr,size,flags,to,tolen); } - + slen=msgdsize(m); // Protect with srtp /* enlarge the buffer for srtp to write its data */ msgpullup(m,msgdsize(m)+SRTP_PAD_BYTES); - slen=m->b_wptr-m->b_rptr; if (stream == rtp_stream) { err=srtp_protect(userData->srtpSend,m->b_rptr,&slen); } else { @@ -661,7 +665,7 @@ // Check if something to receive - rlen=recvfrom(t->session->rtp.socket,(void*)m->b_wptr,m->b_datap->db_lim-m->b_datap->db_base,flags,from,fromlen); + rlen=rtp_session_rtp_recv_abstract(t->session->rtp.socket,m,flags,from,fromlen); if (rlen<=0) { // nothing was received or error: pass the information to caller return rlen; @@ -734,7 +738,7 @@ ZrtpContext *zrtpContext = (ZrtpContext*) t->data; OrtpZrtpContext *userData = (OrtpZrtpContext*) zrtpContext->userData; - int rlen = recvfrom(t->session->rtcp.socket,(void*)m->b_wptr,m->b_datap->db_lim-m->b_datap->db_base,flags,from,fromlen); + int rlen = rtp_session_rtp_recv_abstract(t->session->rtcp.socket,m,flags,from,fromlen); if (rlen<=0) { // nothing was received or error: pass the information to caller return rlen;