Beispiel #1
0
OrtpZrtpContext* ortp_zrtp_multistream_new(OrtpZrtpContext* activeContext, RtpSession *s, OrtpZrtpParams *params) {
	int32_t length;
	char *multiparams=NULL;
	int i=0;
	
	if (!zrtp_isMultiStreamAvailable(activeContext->zrtpContext)) {
		ortp_warning("could't add stream: mutlistream not supported by peer");
	}

	if (zrtp_isMultiStream(activeContext->zrtpContext)) {
		ortp_fatal("Error: should derive multistream from DH or preshared modes only");
	}

	multiparams=zrtp_getMultiStrParams(activeContext->zrtpContext, &length);
	
	ortp_message("ZRTP multiparams length is %d", length);
	for (;i<length;i++) {
		ortp_message("%d", multiparams[i]);
	}

	ortp_message("Initializing ZRTP context");
	ZrtpContext *context = zrtp_CreateWrapper();
	OrtpZrtpContext *userData=createUserData(context);
	userData->session=s;
	ortp_zrtp_configure(context);
	
	zrtp_initializeZrtpEngine(context, &userData->zrtp_cb, userAgentStr, params->zid_file, userData, 0);

	ortp_message("setting zrtp_setMultiStrParams");
	zrtp_setMultiStrParams(context,multiparams,length);

	return ortp_zrtp_configure_context(userData,s,params);
}
Beispiel #2
0
static OrtpZrtpContext* ortp_zrtp_configure_context(OrtpZrtpContext *userData, RtpSession *s, OrtpZrtpParams *params) {
	ZrtpContext *context=userData->zrtpContext;


	if (s->rtp.tr || s->rtcp.tr)
		ortp_warning("Overwriting rtp or rtcp transport with ZRTP one");

	userData->rtpt.data=context;
	userData->rtpt.t_getsocket=ozrtp_rtp_getsocket;
	userData->rtpt.t_sendto=ozrtp_rtp_sendto;
	userData->rtpt.t_recvfrom=ozrtp_rtp_recvfrom;

	userData->rtcpt.data=context;
	userData->rtcpt.t_getsocket=ozrtp_rtcp_getsocket;
	userData->rtcpt.t_sendto=ozrtp_rtcp_sendto;
	userData->rtcpt.t_recvfrom=ozrtp_rtcp_recvfrom;

	rtp_session_set_transports(s, &userData->rtpt, &userData->rtcpt);

	ortp_message("Starting ZRTP engine");
	zrtp_setEnrollmentMode(context,FALSE);//because it is uninitialized in zrtpcpp.
	
	zrtp_startZrtpEngine(context);

	return userData;
}
Beispiel #3
0
static void print_zrtp_packet(const char *info, const uint8_t *rtp) {
	const uint8_t *zmessage=rtp+ZRTP_MESSAGE_OFFSET;
	uint16_t zmessage_seq=get_rtp_seqnumber(rtp);

	char msgType[9];
	parseZrtpMessageType(msgType, zmessage);

/*	uint16_t zmessage_length = get_zrtp_message_length(zmessage);
	uint32_t crc = get_zrtp_packet_crc((uint32_t*) rtp, zmessage_length);

	ortp_message("%s ZRTP seq=%u type=%s CRC=%u, ln=%u",
			info, zmessage_seq, msgType, crc, zmessage_length);
*/

    if (strcmp(zrtpErrorType, msgType) == 0) {
        uint32_t *msg32=(uint32_t*)zmessage;
        uint32_t errcode=ntohl(msg32[3]);
        ortp_error("%s ZRTP %s 0x%x %u", info, msgType, errcode, zmessage_seq);
    } else {
        ortp_message("%s ZRTP %s %u", info, msgType, zmessage_seq);
    }

/*	uint32_t *msg32=(uint32_t*)zmessage;
	int i=0;
	for (; i<zmessage_length; i++) {
		ortp_message("%u", ntohl(msg32[i]));
	}*/
}
Beispiel #4
0
void ortp_zrtp_context_destroy(OrtpZrtpContext *ctx) {
	ortp_message("Stopping ZRTP context");
	zrtp_stopZrtpEngine(ctx->zrtpContext);

	ortp_message("Destroying ZRTP wrapper");
	zrtp_DestroyWrapper(ctx->zrtpContext);

	ortp_message("Destroying ORTP-ZRTP mutex");
	ortp_mutex_destroy(&ctx->mutex);

	ortp_message("Destroying SRTP contexts");
	if (ctx->srtpSend != NULL) srtp_dealloc(ctx->srtpSend);
	if (ctx->srtpRecv != NULL) srtp_dealloc(ctx->srtpRecv);

	ortp_message("ORTP-ZRTP context destroyed");
}
Beispiel #5
0
static void set_high_prio(){
#ifndef _WIN32
	const char *sched_pref=getenv("ORTP_SIMULATOR_SCHED_POLICY");
	int policy=SCHED_OTHER;
	struct sched_param param;
	int result=0;
	char* env_prio_c=NULL;
	int min_prio, max_prio, env_prio;
		
	if (sched_pref && strcasecmp(sched_pref,"SCHED_RR")==0){
		policy=SCHED_RR;
	}else if (sched_pref && strcasecmp(sched_pref,"SCHED_FIFO")==0){
		policy=SCHED_FIFO;
	}

	memset(&param,0,sizeof(param));

	min_prio = sched_get_priority_min(policy);
	max_prio = sched_get_priority_max(policy);
	env_prio_c = getenv("ORTP_SIMULATOR_SCHED_PRIO");

	env_prio = (env_prio_c == NULL)?max_prio:atoi(env_prio_c);

	env_prio = MAX(MIN(env_prio, max_prio), min_prio);

	param.sched_priority=env_prio;
	if((result=pthread_setschedparam(pthread_self(),policy, &param))) {
		ortp_warning("Ortp simulator: set pthread_setschedparam failed: %s",strerror(result));
	} else {
		ortp_message("ortp network simulator: sched policy set to %s and priority value (%i)",
				sched_policy_to_string(policy), param.sched_priority);
	}
#endif
}
Beispiel #6
0
static void rtp_session_create_and_send_rtcp_packet(RtpSession *session, bool_t full) {
	mblk_t *m=NULL;
	bool_t is_sr = FALSE;

	if (session->rtp.last_rtcp_packet_count < session->stats.packet_sent) {
		m = make_sr(session);
		session->rtp.last_rtcp_packet_count = (uint32_t)session->stats.packet_sent;
		is_sr = TRUE;
	} else if (session->stats.packet_recv > 0) {
		/* Don't send RR when no packet are received yet */
		m = make_rr(session);
		is_sr = FALSE;
	}
	if (m != NULL) {
		append_sdes(session, m, full);
		if ((full == TRUE) && (session->rtcp.xr_conf.enabled == TRUE)) {
			append_xr_packets(session, m);
		}
		if (rtp_session_avpf_enabled(session) == TRUE) {
			append_fb_packets(session, m);
		}
		/* Send the compound packet */
		notify_sent_rtcp(session, m);
		ortp_message("Sending RTCP %s compound message on session [%p].",(is_sr ? "SR" : "RR"), session);
		rtp_session_rtcp_send(session, m);
	}
}
Beispiel #7
0
int main(int argc, char *argv[])
{
	RtpSession *session;
	unsigned char buffer[160];
	int i;
	FILE *infile;
	char *ssrc;
	uint32_t user_ts=0;
	int tel=0;
	
	if (argc<4){
		printf(help);
		return -1;
	}
	
	ortp_init();
	ortp_scheduler_init();
	
	/* set the telephony event payload type to 96 in the av profile.*/
	rtp_profile_set_payload(&av_profile,96,&payload_type_telephone_event);
	
	session=rtp_session_new(RTP_SESSION_SENDONLY);
	
	rtp_session_set_scheduling_mode(session,1);
	rtp_session_set_blocking_mode(session,1);
	rtp_session_set_remote_addr(session,argv[2],atoi(argv[3]));
	rtp_session_set_send_payload_type(session,0);
	
	ssrc=getenv("SSRC");
	if (ssrc!=NULL) {
		printf("using SSRC=%i.\n",atoi(ssrc));
		rtp_session_set_ssrc(session,atoi(ssrc));
	}
		
	infile=fopen(argv[1],"rb");
	if (infile==NULL) {
		perror("Cannot open file");
		return -1;
	}
	signal(SIGINT,stophandler);
	while( ((i=fread(buffer,1,160,infile))>0) && (runcond) )
	{
		//ortp_message("Sending packet.");
		rtp_session_send_with_ts(session,buffer,i,user_ts);
		user_ts+=160;
		tel++;
		if (tel==50){
			tel=0;
			ortp_message("Sending telephony event packet.");
			rtp_session_send_dtmf(session,'*',user_ts);
			user_ts+=160+160+160; /* the duration of the dtmf */
		}
	}
	fclose(infile);
	rtp_session_destroy(session);
	ortp_exit();
	ortp_global_stats_display();
	return 0;
}
Beispiel #8
0
void rtp_session_enable_network_simulation(RtpSession *session, const OrtpNetworkSimulatorParams *params){
	OrtpNetworkSimulatorCtx *sim=session->net_sim_ctx;
	if (params->enabled){
		if (sim==NULL)
			sim=simulator_ctx_new();
		sim->drop_by_congestion=sim->drop_by_loss=sim->total_count=0;
		sim->params=*params;
		if (sim->params.jitter_burst_density>0 && sim->params.jitter_strength>0 && sim->params.max_bandwidth==0){
			sim->params.max_bandwidth=1024000;
			ortp_message("Network simulation: jitter requested but max_bandwidth is not set. Using default value of %f bits/s.",
				sim->params.max_bandwidth);
		}
		if (sim->params.max_bandwidth && sim->params.max_buffer_size==0) {
			sim->params.max_buffer_size=sim->params.max_bandwidth;
			ortp_message("Network simulation: Max buffer size not set for RTP session [%p], using [%i]",session,sim->params.max_buffer_size);
		}
		session->net_sim_ctx=sim;
		if ((params->mode==OrtpNetworkSimulatorOutbound || params->mode==OrtpNetworkSimulatorOutboundControlled) && !sim->thread_started){
			sim->thread_started=TRUE;
			ortp_thread_create(&sim->thread, NULL, outboud_simulator_thread, session);
		}

		ortp_message("Network simulation: enabled with the following parameters:\n"
				"\tlatency=%d\n"
				"\tloss_rate=%.1f\n"
				"\tconsecutive_loss_probability=%.1f\n"
				"\tmax_bandwidth=%.1f\n"
				"\tmax_buffer_size=%d\n"
				"\tjitter_density=%.1f\n"
				"\tjitter_strength=%.1f\n"
				"\tmode=%s\n",
				params->latency,
				params->loss_rate,
				params->consecutive_loss_probability,
				params->max_bandwidth,
				params->max_buffer_size,
				params->jitter_burst_density,
				params->jitter_strength,
				ortp_network_simulator_mode_to_string(params->mode)
    			);
	}else{
		session->net_sim_ctx=NULL;
		if (sim!=NULL) ortp_network_simulator_destroy(sim);
	}
}
Beispiel #9
0
OrtpZrtpContext* ortp_zrtp_context_new(RtpSession *s, OrtpZrtpParams *params){
	ZrtpContext *context = zrtp_CreateWrapper();
	OrtpZrtpContext *userData=createUserData(context);
	userData->session=s;
	ortp_zrtp_configure(context);
	ortp_message("Initialized ZRTP context");
	zrtp_initializeZrtpEngine(context, &userData->zrtp_cb, userAgentStr, params->zid_file, userData, 0);
	return ortp_zrtp_configure_context(userData,s,params);
}
Beispiel #10
0
static mblk_t *simulate_bandwidth_limit(RtpSession *session, mblk_t *input){
	OrtpNetworkSimulatorCtx *sim=session->net_sim_ctx;
	struct timeval current;
	int64_t elapsed;
	int bits;
	mblk_t *output=NULL;
#ifdef ORTP_INET6
	int overhead=(session->rtp.sockfamily==AF_INET6) ? IP6_UDP_OVERHEAD : IP_UDP_OVERHEAD;
#else
	int overhead=IP_UDP_OVERHEAD;
#endif
	gettimeofday(&current,NULL);
	
	if (sim->last_check.tv_sec==0){
		sim->last_check=current;
		sim->bit_budget=0;
	}
	/*update the budget */
	elapsed=elapsed_us(&sim->last_check,&current);
	sim->bit_budget+=(elapsed*(int64_t)sim->params.max_bandwidth)/1000000LL;
	sim->last_check=current;
	/* queue the packet for sending*/
	if (input){
		putq(&sim->q,input);
		bits=(msgdsize(input)+overhead)*8;
		sim->qsize+=bits;
	}
	/*flow control*/
	while (sim->qsize>=sim->params.max_bandwidth){
		ortp_message("rtp_session_network_simulate(): discarding packets.");
		output=getq(&sim->q);
		if (output){
			bits=(msgdsize(output)+overhead)*8;
			sim->qsize-=bits;
			freemsg(output);
		}
	}
	
	output=NULL;
	
	/*see if we can output a packet*/
	if (sim->bit_budget>=0){
		output=getq(&sim->q);
		if (output){
			bits=(msgdsize(output)+overhead)*8;
			sim->bit_budget-=bits;
			sim->qsize-=bits;
		}
	}
	if (output==NULL && input==NULL && sim->bit_budget>=0){
		/* unused budget is lost...*/
		sim->last_check.tv_sec=0;
	}
	return output;
}
Beispiel #11
0
/**
 *	Initialize the oRTP library. You should call this function first before using
 *	oRTP API.
**/
void ortp_init()
{
	if (ortp_initialized++) return;

#ifdef _WIN32
	win32_init_sockets();
#endif
	ortp_init_logger();
	av_profile_init(&av_profile);
	ortp_global_stats_reset();
	init_random_number_generator();

	ortp_message("oRTP-" ORTP_VERSION " initialized.");
}
Beispiel #12
0
/**
 * Switch off the security for the defined part.
 *
 * @param ctx
 *    Pointer to the opaque ZrtpContext structure.
 * @param part Defines for which part (sender or receiver) to
 *    switch off security
 */
static void ozrtp_srtpSecretsOff (ZrtpContext* ctx, int32_t part ) {
	OrtpZrtpContext *userData = user_data(ctx);

	if (userData->srtpRecv != NULL) {
		srtp_dealloc(userData->srtpRecv);
		userData->srtpRecv=NULL;
	}

	if (userData->srtpSend != NULL) {
		srtp_dealloc(userData->srtpSend);
		userData->srtpSend=NULL;
	}

	ortp_message("ZRTP secrets off");
}
Beispiel #13
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;

#ifdef WIN32
	win32_init_sockets();
#endif

	av_profile_init(&av_profile);
	ortp_global_stats_reset();
	init_random_number_generator();
	ortp_message("oRTP-" ORTP_VERSION " initialized.");
}
Beispiel #14
0
err_status_t ortp_srtp_init(void)
{
	
	err_status_t st=0;
	ortp_message("srtp init");
	if (!srtp_init_done) {
		st=srtp_init();
		if (st==0) {
			srtp_init_done++;
		}else{
			ortp_fatal("Couldn't initialize SRTP library.");
			err_reporting_init("oRTP");
		}
	}else srtp_init_done++;
	return st;
}
Beispiel #15
0
/**
 * Switch on the security.
 *
 * ZRTP calls this method after it has computed the SAS and check
 * if it is verified or not. In addition ZRTP provides information
 * about the cipher algorithm and key length for the SRTP session.
 *
 * This method must enable SRTP processing if it was not enabled
 * during sertSecretsReady().
 *
 * @param ctx
 *    Pointer to the opaque ZrtpContext structure.
 * @param c The name of the used cipher algorithm and mode, or
 *    NULL
 *
 * @param s The SAS string
 *
 * @param verified if <code>verified</code> is true then SAS was
 *    verified by both parties during a previous call.
 */
static void ozrtp_rtpSecretsOn (ZrtpContext* ctx, char* c, char* s, int32_t verified ){
//	OrtpZrtpContext *userData = user_data(ctx);

	// srtp processing is enabled in SecretsReady fuction when receiver secrets are ready
	// Indeed, the secrets on is called before both parts are given to secretsReady.

	OrtpEventData *eventData;
	OrtpEvent *ev;
	ev=ortp_event_new(ORTP_EVENT_ZRTP_SAS_READY);
	eventData=ortp_event_get_data(ev);
	memcpy(eventData->info.zrtp_sas.sas,s,4);
	eventData->info.zrtp_sas.sas[4]=0;
	eventData->info.zrtp_sas.verified=(verified != 0) ? TRUE : FALSE;
	rtp_session_dispatch_event(user_data(ctx)->session, ev);
	ortp_message("ZRTP secrets on: SAS is %s previously verified %s - algo %s", s, verified == 0 ? "no" : "yes", c);
}
Beispiel #16
0
void ortp_network_simulator_destroy(OrtpNetworkSimulatorCtx *sim){
	int drop_by_flush=sim->latency_q.q_mcount+sim->q.q_mcount;
	if (sim->total_count>0){
		ortp_message("Network simulation: destroyed. Statistics are:"
			"%d/%d(%.1f%%, param=%.1f) packets dropped by loss, "
			"%d/%d(%.1f%%) packets dropped by congestion, "
			"%d/%d(%.1f%%) packets flushed."
			, sim->drop_by_loss, sim->total_count, sim->drop_by_loss*100.f/sim->total_count, sim->params.loss_rate
			, sim->drop_by_congestion, sim->total_count, sim->drop_by_congestion*100.f/sim->total_count
			, drop_by_flush, sim->total_count, drop_by_flush*100.f/sim->total_count
		);
	}
	flushq(&sim->latency_q,0);
	flushq(&sim->q,0);
	flushq(&sim->send_q,0);
	if (sim->thread_started){
		sim->thread_started=FALSE;
		ortp_thread_join(sim->thread, NULL);
	}
	ortp_mutex_destroy(&sim->mutex);
	ortp_free(sim);
}
Beispiel #17
0
int main(int argc, char *argv[])
{
	RtpSession *session;
	unsigned char buffer[160];
	int i;
	FILE *infile;
	char *ssrc;
	uint32_t packet_ts=0,send_ts=0;
	uint32_t send_ts_inc=160;
	int clockslide=0;
	int jitter=0;
	if (argc<4){
		printf("%s",help);
		return -1;
	}
	for(i=4;i<argc;i++){
		if (strcmp(argv[i],"--with-clockslide")==0){
			i++;
			if (i>=argc) {
				printf("%s",help);
				return -1;
			}
			clockslide=atoi(argv[i]);
			ortp_message("Using clockslide of %i milisecond every 50 packets.",clockslide);
		}else if (strcmp(argv[i],"--with-ptime")==0){
			ortp_message("Ptime related jitter will be added to outgoing stream.");
			i++;
			if (i>=argc) {
				printf("%s",help);
				return -1;
			}
			jitter=atoi(argv[i]);
			send_ts_inc=jitter*8;
		}
	}
	
	ortp_init();
	ortp_scheduler_init();
	ortp_set_log_level_mask(NULL, ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR);
	session=rtp_session_new(RTP_SESSION_SENDONLY);	
	
	rtp_session_set_scheduling_mode(session,1);
	rtp_session_set_blocking_mode(session,1);
	rtp_session_set_connected_mode(session,TRUE);
	rtp_session_set_remote_addr(session,argv[2],atoi(argv[3]));
	rtp_session_set_payload_type(session,0);
	
	ssrc=getenv("SSRC");
	if (ssrc!=NULL) {
		printf("using SSRC=%i.\n",atoi(ssrc));
		rtp_session_set_ssrc(session,atoi(ssrc));
	}
		
	#ifndef _WIN32
	infile=fopen(argv[1],"r");
	#else
	infile=fopen(argv[1],"rb");
	#endif

	if (infile==NULL) {
		perror("Cannot open file");
		return -1;
	}

	signal(SIGINT,stophandler);
	while( ((i=fread(buffer,1,160,infile))>0) && (runcond) )
	{
		mblk_t *m=rtp_session_create_packet(session,RTP_FIXED_HEADER_SIZE,buffer,i);
		__rtp_session_sendm_with_ts(session,m,packet_ts,send_ts);
		packet_ts+=160;
		if ((send_ts+send_ts_inc)<=packet_ts){
			send_ts+=send_ts_inc;
		}
		if (clockslide!=0 && send_ts%(160*50)==0){
			ortp_message("Clock sliding of %i miliseconds now",clockslide);
			rtp_session_make_time_distorsion(session,clockslide);
		}
	}

	fclose(infile);
	rtp_session_destroy(session);
	ortp_exit();
	ortp_global_stats_display();

	return 0;
}
Beispiel #18
0
void jitter_control_dump_stats(JitterControl *ctl){
	ortp_message("JitterControl:\n\tslide=%g,jitter=%g,count=%i",
			ctl->slide,ctl->jitter, ctl->count);
}
Beispiel #19
0
OrtpZrtpContext* ortp_zrtp_multistream_new(OrtpZrtpContext* activeContext, RtpSession *s, OrtpZrtpParams *params) {
	ortp_message("ZRTP is disabled - not implemented yet - not adding stream");
	return NULL;
}
Beispiel #20
0
OrtpZrtpContext* ortp_zrtp_context_new(RtpSession *s, OrtpZrtpParams *params){
	ortp_message("ZRTP is disabled - not implemented yet");
	return NULL;
}
Beispiel #21
0
void jitter_control_dump_stats(JitterControl *ctl){
	ortp_message("JitterControl:\n\tslide=%g,jitter=%g,adapt_jitt_comp_ts=%i,corrective_slide=%i, count=%i",
			(double)ctl->slide,ctl->jitter, ctl->adapt_jitt_comp_ts, ctl->corrective_slide,ctl->count);
}
Beispiel #22
0
err_status_t ortp_srtp_init(void)
{
	ortp_message("srtp init");
	return srtp_init();
}
Beispiel #23
0
/**
* Send information messages to the hosting environment.
*
* The ZRTP implementation uses this method to send information
* messages to the host. Along with the message ZRTP provides a
* severity indicator that defines: Info, Warning, Error,
* Alert. Refer to the <code>MessageSeverity</code> enum above.
*
* @param ctx
*    Pointer to the opaque ZrtpContext structure.
* @param severity
*     This defines the message's severity
* @param subCode
*     The subcode identifying the reason.
* @see ZrtpCodes#MessageSeverity
*/
static void ozrtp_sendInfo (ZrtpContext* ctx, int32_t severity, int32_t subCode ) {
	const char* submsg;
	switch (subCode) {
		case zrtp_InfoHelloReceived:
			/*!< Hello received, preparing a Commit */
			submsg="zrtp_InfoHelloReceived";
			break;
		case zrtp_InfoCommitDHGenerated:
			/*!< Commit: Generated a public DH key */
			submsg="zrtp_InfoCommitDHGenerated";
			break;
		case zrtp_InfoRespCommitReceived:
			 /*!< Responder: Commit received, preparing DHPart1 */
			submsg="zrtp_InfoRespCommitReceived";
			break;
		case zrtp_InfoDH1DHGenerated:
			/*!< DH1Part: Generated a public DH key */
			submsg="zrtp_InfoDH1DHGenerated";
			break;
		case zrtp_InfoInitDH1Received:
           /*!< Initiator: DHPart1 received, preparing DHPart2 */
			submsg="zrtp_InfoInitDH1Received";
			break;
		case zrtp_InfoRespDH2Received:
			/*!< Responder: DHPart2 received, preparing Confirm1 */
			submsg="zrtp_InfoRespDH2Received";
			break;
		case zrtp_InfoInitConf1Received:
			/*!< Initiator: Confirm1 received, preparing Confirm2 */
			submsg="zrtp_InfoInitConf1Received";
			break;
		case zrtp_InfoRespConf2Received:
			/*!< Responder: Confirm2 received, preparing Conf2Ack */
			submsg="zrtp_InfoRespConf2Received";
			break;
		case zrtp_InfoRSMatchFound:
			/*!< At least one retained secrets matches - security OK */
			submsg="zrtp_InfoRSMatchFound";
			break;
		case zrtp_InfoSecureStateOn:
			/*!< Entered secure state */
			submsg="zrtp_InfoSecureStateOn";
			break;
		case zrtp_InfoSecureStateOff:
			/*!< No more security for this session */
			submsg="zrtp_InfoSecureStateOff";
			break;
		default:
			submsg="unkwown";
			break;
	}

	switch (severity) {
		case zrtp_Info:
			ortp_message("ZRTP INFO %s",submsg);
			break;
		case zrtp_Warning: /*!< A Warning message - security can be established */
			ortp_warning("ZRTP %s",submsg);
			break;
		case zrtp_Severe:/*!< Severe error, security will not be established */
			ortp_error("ZRTP SEVERE %s",submsg);
			break;
		case zrtp_ZrtpError:
			ortp_error("ZRTP ERROR %s",submsg);
			break;
		default:
			ortp_error("ZRTP UNKNOWN ERROR %s",submsg);
			break;
	}


	if (subCode == zrtp_InfoSecureStateOn || subCode == zrtp_InfoSecureStateOff) {
		OrtpEventData *eventData;
		OrtpEvent *ev;
		ev=ortp_event_new(ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED);
		eventData=ortp_event_get_data(ev);
		eventData->info.zrtp_stream_encrypted=(subCode == zrtp_InfoSecureStateOn);
		rtp_session_dispatch_event(user_data(ctx)->session, ev);
	}
}
Beispiel #24
0
/**
 * SRTP crypto data ready for the sender or receiver.
 *
 * The ZRTP implementation calls this method right after all SRTP
 * secrets are computed and ready to be used. The parameter points
 * to a structure that contains pointers to the SRTP secrets and a
 * <code>enum Role</code>. The called method (the implementation
 * of this abstract method) must either copy the pointers to the SRTP
 * data or the SRTP data itself to a save place. The SrtpSecret_t
 * structure is destroyed after the callback method returns to the
 * ZRTP implementation.
 *
 * The SRTP data themselves are obtained in the ZRtp object and are
 * valid as long as the ZRtp object is active. TheZRtp's
 * destructor clears the secrets. Thus the called method needs to
 * save the pointers only, ZRtp takes care of the data.
 *
 * The implementing class may enable SRTP processing in this
 * method or delay it to srtpSecertsOn().
 *
 * @param ctx
 *    Pointer to the opaque ZrtpContext structure.
 * @param secrets A pointer to a SrtpSecret_t structure that
 *     contains all necessary data.
 *
 * @param part for which part (Sender or Receiver) this data is
 *     valid.
 *
 * @return Returns false if something went wrong during
 *    initialization of SRTP context, for example memory shortage.
 */
static int32_t ozrtp_srtpSecretsReady (ZrtpContext* ctx, C_SrtpSecret_t* secrets, int32_t part ) {
	srtp_policy_t policy;
	err_status_t srtpCreateStatus;
	err_status_t addStreamStatus;
	OrtpZrtpContext *userData = user_data(ctx);

	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) {
		ortp_fatal("unsupported authentication algorithm by srtp");
	}

	if (secrets->symEncAlgorithm != zrtp_Aes) {
		ortp_fatal("unsupported cipher algorithm by srtp");
	}

	/*
	 * 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 */
		int32_t peerRole=secrets->role == Initiator ? Responder : Initiator;
		policy.key=key_with_salt(secrets,peerRole);
		addStreamStatus=srtp_add_stream(userData->srtpRecv, &policy);
	}

	ortp_free(policy.key);

	if (srtpCreateStatus != err_status_ok) {
		ortp_error("ZRTP Error %u during creation of SRTP context for %s",
			srtpCreateStatus, (part == ForSender) ? "sender" : "receiver");
		return 0;
	}
	if (addStreamStatus != err_status_ok) {
		ortp_error("ZRTP Error %u during addition of SRTP stream for %s",
			addStreamStatus, (part == ForSender) ? "sender" : "receiver");
		return 0;
	}
	return 1;
}
Beispiel #25
0
static int ozrtp_rtp_recvfrom(RtpTransport *t, mblk_t *m, int flags, struct sockaddr *from, socklen_t *fromlen){
	int rlen;

	ZrtpContext *zrtpContext = (ZrtpContext*) t->data;
	OrtpZrtpContext *userData = (OrtpZrtpContext*) zrtpContext->userData;


	// Do extra stuff first
	check_timer(zrtpContext, userData);


	// Check if something to receive
	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;
	}

	uint8_t* rtp = m->b_rptr;
	int rtpVersion = ((rtp_header_t*)rtp)->version;

	// If plain or secured RTP
	if (rtpVersion == 2) {
		if (userData->srtpRecv != NULL && zrtp_inState(zrtpContext, SecureState)) {
			// probably srtp packet, unprotect
			err_status_t err = srtp_unprotect(userData->srtpRecv,m->b_wptr,&rlen);
			if (err != err_status_ok) {
				ortp_warning("srtp_unprotect failed; packet may be plain RTP");
			}
		}
		// in both cases (RTP plain and deciphered srtp)
		return rlen;
	}


	// if ZRTP packet, send to engine
	uint32_t *magicField=(uint32_t *)(rtp + 4);
	if (rlen >= ZRTP_MIN_MSG_LENGTH && rtpVersion==0 && ntohl(*magicField) == ZRTP_MAGIC) {
		print_zrtp_packet("received", rtp);
		uint8_t *ext_header = rtp+ZRTP_MESSAGE_OFFSET;
		uint16_t ext_length = get_zrtp_message_length(ext_header);
		char messageType[9];
		parseZrtpMessageType(messageType, ext_header);

		// Check max length
		if (rlen < 12 + ext_length + 4) {
			ortp_warning("Received malformed ZRTP-like packet: size %d (expected %d)", rlen, 12 + ext_length + 4);
			return 0;
		}

		// Check sequence number
		uint16_t seq_number = get_rtp_seqnumber(rtp);
		if (userData->last_recv_zrtp_seq_number != 0 && seq_number <= userData->last_recv_zrtp_seq_number) {
			// Discard out of order ZRTP packet
			ortp_message("Discarding received out of order zrtp packet: %d (expected >%d)",
					seq_number, userData->last_recv_zrtp_seq_number);
			return 0;
		}


		// Check packet checksum
		uint32_t rcv_crc = get_zrtp_packet_crc((uint32_t*)rtp, ext_length);
		uint32_t zrtp_total_packet_length = ZRTP_MESSAGE_OFFSET + 4*ext_length + 4;
		if (!zrtp_CheckCksum(rtp, zrtp_total_packet_length-CRC_SIZE, rcv_crc)) {
			ortp_warning("Bad ZRTP packet checksum %u total %u", rcv_crc, zrtp_total_packet_length);
			return 0;
		}

		uint32_t peerssrc = ntohl(*(uint32_t*)(rtp+8));
#if HAVE_zrtpcpp_with_len
		zrtp_processZrtpMessage(zrtpContext, ext_header, peerssrc,rlen);
#else
		zrtp_processZrtpMessage(zrtpContext, ext_header, peerssrc);
#endif
		userData->last_recv_zrtp_seq_number=seq_number;
		return 0;
		}
	else {
		// Not a ZRTP packet, accept it
		return rlen;
	}
}
Beispiel #26
0
int main(int argc, char *argv[])
{
	RtpSession *session;
	unsigned char buffer[160];
	int i;
	FILE *infile;
	char *ssrc;
	uint32_t user_ts=0;
	int clockslide=0;
	int jitter=0;
	if (argc<4){
		printf("%s", help);
		return -1;
	}
	for(i=4;i<argc;i++){
		if (strcmp(argv[i],"--with-clockslide")==0){
			i++;
			if (i>=argc) {
				printf("%s", help);
				return -1;
			}
			clockslide=atoi(argv[i]);
			ortp_message("Using clockslide of %i milisecond every 50 packets.",clockslide);
		}else if (strcmp(argv[i],"--with-jitter")==0){
			ortp_message("Jitter will be added to outgoing stream.");
			i++;
			if (i>=argc) {
				printf("%s", help);
				return -1;
			}
			jitter=atoi(argv[i]);
		}
	}
	
	ortp_init();
	ortp_scheduler_init();
	ortp_set_log_level_mask(NULL, ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR);
	session=rtp_session_new(RTP_SESSION_SENDONLY);	
	
	rtp_session_set_scheduling_mode(session,1);
	rtp_session_set_blocking_mode(session,1);
	rtp_session_set_connected_mode(session,TRUE);
	rtp_session_set_remote_addr(session,argv[2],atoi(argv[3]));
	rtp_session_set_payload_type(session,0);
	
	ssrc=getenv("SSRC");
	if (ssrc!=NULL) {
		printf("using SSRC=%i.\n",atoi(ssrc));
		rtp_session_set_ssrc(session,atoi(ssrc));
	}
		
	#ifndef _WIN32
	infile=fopen(argv[1],"r");
	#else
	infile=fopen(argv[1],"rb");
	#endif

	if (infile==NULL) {
		perror("Cannot open file");
		return -1;
	}

	signal(SIGINT,stophandler);
	while( ((i=fread(buffer,1,160,infile))>0) && (runcond) )
	{
		rtp_session_send_with_ts(session,buffer,i,user_ts);
		user_ts+=160;
		if (clockslide!=0 && user_ts%(160*50)==0){
			ortp_message("Clock sliding of %i miliseconds now",clockslide);
			rtp_session_make_time_distorsion(session,clockslide);
		}
		/*this will simulate a burst of late packets */
		if (jitter && (user_ts%(8000)==0)) {
			ortp_message("Simulating late packets now (%i milliseconds)",jitter);
			ortp_sleep_ms(jitter);
		}
	}

	fclose(infile);
	rtp_session_destroy(session);
	ortp_exit();
	ortp_global_stats_display();

	return 0;
}