520 likes | 556 Views
Porting VoIP Applications to DCCP. Speaker: Jia-Yu Wang Adviser: Quincy Wu Date:2008/06/05. Outline. Introduction DCCP Connection Linphone System components oRTP Mediastream2 Install Linphone Linphone original Function call Porting Linphone to DCCP Implementing DCCP Function call
E N D
Porting VoIP Applications to DCCP Speaker: Jia-Yu Wang Adviser: Quincy Wu Date:2008/06/05
Outline • Introduction • DCCP Connection • Linphone • System components • oRTP • Mediastream2 • Install Linphone • Linphone original Function call • Porting Linphone to DCCP • Implementing DCCP Function call • Implementation • Conclusions • Future work • Reference
Introduction(1/3) • Datagram Congestion Control Protocol (RFC 4340)
Introduction(2/3) • Unreliable • No re-transmissions • Reliable handshakes for connection setup and teardown • Has modular congestion control • Can detect congestion and take avoiding action • Different algorithms can be selected – CCID • TCP-like (CCID2) • TCP Friendly Rate Control (CCID3) • Packet sequence numbers
Introduction(3/3) • DCCP Application • Video streaming • Audio streaming • IP Telephony
Linphone(1/2) • Linphone is an internet phone • Linphone complies to the SIP protocol • Linphone is free-software (or open-source), you can download and redistribute it freely
Linphone(2/2) • SIP proxy support: registrar, proxies, with digest authentication • DTMF (telephone tones) support using SIP INFO or RFC2833 • Supports IPv6 • STUN support for traversal of UDP NATs (=firewall) • Text instant messaging and presence (using the SIMPLE standart)
System components(1/2) • Audio codecs:
oRTP • Written in C, works under Linux (and probably any Unix) and Windows. • Implement the RFC3550 (RTP) with a easy to use API with high and low level access. • Supports part of RFC2833 for telephone events over RTP. From : http://www.linphone.org/index.php/eng/code_review/ortp
mediastream2 • Send and receive RTP packets • Encode and decode the following formats: speex, G711, GSM, H263, theora. • Read and write from/to a wav file • Echo cancelation, using the extraordinary echo canceler algorithm from the speex library From : http://www.linphone.org/index.php/eng/code_review/mediastreamer2
Install Linphone(1/2) • perl-XML-Parser • perl-XML-Parser-2.34-6.1.2.2.1.i386.rpm • speex-devel • speex-devel-1.2-0.2.beta1.i386.rpm • readline-devel • readline-devel-5.2-4.fc7.i386.rpm • libosip2 • libosip2-2.2.2.tar.gz • ./configure • make • make install
Install Linphone(2/2) • linphone-1.7.1 • ./configure –disable-video • make • make install • # linphone • http://ms11.voip.edu.tw/~jiayu/research/linphone-1.7.1_full_fc7_i386.tar.gz
Porting Linphone to DCCP • Create 2 RTP Session • DCCP connection is uni-directional • Connect-Oriented • Receiver socket need to use Blocking for accept • Receiver socket need to accept the establishment of waiting for sender socket connect • Socket • Create socket need using DCCP protocol
Conclusions • Implementing RTP over DCCP • 2 RTP session to establishment the use of call • DCCP connection is uni-directional • Porting Linphone to DCCP
Future work • UDP conversion and DCCP • NAT handling • Defined other CCID (CCID4 …)
Reference • Datagram Congestion Control Protocol (RFC 4340) • CCID2-TCP-like Congestion Control (RFC 4341) • CCID3-TCP-Friendly Rate Control (TFRC) (RFC4342) • RTP and the Datagram Congestion Control Protocol (DCCP) • draft-ietf-dccp-rtp-07.txt • Linphne • http://www.linphone.org/index.php/eng
Linphone original 1 • oRTP/rtpsession_inet.c • static ortp_socket_t create_and_bind(const char *addr, int port, int *sock_family) • 建立socket並bind • static ortp_socket_t create_and_bind_random(const char *localip, int *sock_family, int *port) • 建立random port number的socket
Linphone original 2 • oRTP/rtpsession_inet.c • Int rtp_session_set_local_addr (RtpSession * session, const char * addr, int port) • 設定local address • 檢查是否有輸入port值 if (port>0){ create_and_bind(addr,port,&sockfamily); }else{ create_and_bind_random(addr,&sockfamily,&port); }
Linphone original 3 • oRTP/rtpsession_inet.c • int rtp_session_set_remote_addr (RtpSession * session, const char * addr, int port) • 設定遠端的address • 檢查socket是否未建立 if (session->rtp.socket == -1){ if (res0->ai_addr->sa_family==AF_INET6){ rtp_session_set_local_addr (session, "::", -1); } else { rtp_session_set_local_addr (session, "0.0.0.0", -1); } }
Linphone original 4 • oRTP/rtpsession_inet.c • int rtp_session_rtp_recv (RtpSession * session, uint32_t user_ts) • 接收rtp封包
Linphone original 5 • oRTP/rtpsession_inet.c • rtp_session_rtp_send (RtpSession * session, mblk_t * m) • 傳送rtp封包
Linphone original 6 • oRTP/rtpsession.c • rtp_session_recvm_with_ts(RtpSession * session, uint32_t user_ts) • 使用rtp_session_rtp_recv()接收rtp封包,加入timestamp。
Linphone original 7 • oRTP/rtpsession.c • int rtp_session_sendm_with_ts (RtpSession * session, mblk_t *mp, uint32_t timestamp) • 使用rtp_session_rtp_send()傳送rtp封包,加入timestamp。
Linphone original 8 • mediastream2/msrtp.c • static void receiver_preprocess(MSFilter * f) • 設定receive端的payload
Linphone original 9 • mediastream2/msrtp.c • static void receiver_process(MSFilter * f) • 進行接收rtp封包的process • rtp_session_recvm_with_ts()
Linphone original 10 • mediastream2/msrtp.c • static void sender_process(MSFilter * f) • 進行傳送rtp封包的process • rtp_session_sendm_with_ts()
Linphone original 11 • mediastream2/audiostream.c • int audio_stream_start_full(AudioStream *stream, RtpProfile *profile, const char *remip,int remport, int payload,int jitt_comp, const char *infile, const char *outfile, MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec) • 建立session的設定 • 產生soundread執行緒,進行傳送rtp封包 • ms_ticker_attach(stream->ticker,stream->soundread); • 產生rtprecv執行緒,進行rtp封包接收 • ms_ticker_attach(stream->ticker,stream->rtprecv);
Linphone original 12 • mediastream2/audiostream.c • AudioStream *audio_stream_new(int locport, bool_t ipv6) • 產生audio stream後,建立rtp session • create_duplex_rtpsession();
Linphone original 13 • mediastream2/audiostream.c • RtpSession * create_duplex_rtpsession( int locport, bool_t ipv6) • 建立session • rtp_session_new(RTP_SESSION_SENDRECV); • 建立socket • rtp_session_set_local_addr(rtpr,ipv6 ? "::" : "0.0.0.0",locport);
Linphone original 14 • mediastream2/audiostream.c • int audio_stream_start_now(AudioStream *stream, RtpProfile * prof, const char *remip, int remport, int payload_type, int jitt_comp, MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec) • 進行stream傳輸 • audio_stream_start_full();
Implementing DCCP_1 1 • mediastream2/audiostream.c • AudioStream *audio_stream_new(int locport, bool_t ipv6) • 產生一個audio stream後,建立二個rtp session • create_duplex_rtpsession_recv(); • create_duplex_rtpsession_send();
Implementing DCCP_1 2 • mediastream2/audiostream.c • RtpSession * create_duplex_rtpsession_recv( int locport, bool_t ipv6) • 建立第一個session,receive端用,並建立socket等待accept • ortp_init(); • ortp_scheduler_init(); • rtp_session_new(RTP_SESSION_SENDRECV); • rtp_session_set_scheduling_mode(rtpr,1); • rtp_session_set_blocking_mode(rtpr,1); • rtp_session_set_connected_mode(rtpr,TRUE); • rtp_session_set_local_addr(rtpr,ipv6 ? “::” : “0.0.0.0”,locport);
Implementing DCCP_1 3 • mediastream2/audiostream.c • RtpSession * create_duplex_rtpsession_send( int locport, bool_t ipv6) • 建立第二個session,send端用 • ortp_init(); • ortp_scheduler_init(); • rtp_session_new(RTP_SESSION_SENDRECV); • rtp_session_set_scheduling_mode(rtpr,1); • rtp_session_set_blocking_mode(rtpr,1); • rtp_session_set_connected_mode(rtpr,TRUE);
Implementing DCCP_1 4 • oRTP/rtpsession_inet.c • static ortp_socket_t create_and_bind_recv(const char *addr, int port, int *sock_family) • 建立socket並bind及listen (receive端) • 建立DCCP的預設使用值 SOCK_DCCP=6; SOL_DCCP=269; DCCP_SOCKOPT_PACKET_SIZE=1; DCCP_SOCKOPT_SERVICE=2; IPPROTO_DCCP=33; • socket(ai_family, SOCK_DCCP, IPPROTO_DCCP); • setsockopt(sock,SOL_DCCP,DCCP_SOCKOPT_PACKET_SIZE, (char*)&pkt_size,sizeof(pkt_size)); • setsockopt(sock,SOL_DCCP,DCCP_SOCKOPT_SERVICE,(char*)&pkt_size,sizeof(pkt_size)); • set_non_blocking_socket (sock); //將socket設定為non_blocking,由於DCCP為Connect-Oriented 必須使用accept(),所以不能non_blocking。
Implementing DCCP_2 1 • mediastream2/audiostream.c • int audio_stream_start_now(AudioStream *stream, RtpProfile * prof, const char *remip, int remport, int payload_type, int jitt_comp, MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec) • 進行stream傳輸,先進行send,再進行recv • audio_stream_start_full_send(); • audio_stream_start_full_recv();
Implementing DCCP_2 2 • mediastream2/audiostream.c • int audio_stream_start_full_recv(AudioStream *stream, RtpProfile *profile, const char *remip,int remport, int payload,int jitt_comp, const char *infile, const char *outfile, MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec) • 建立第一個session的設定(receive端) • 產生rtprecv執行緒,進行rtp封包接收 • ms_ticker_attach(stream->ticker,stream->rtprecv);
Implementing DCCP_2 3 • mediastream2/audiostream.c • int audio_stream_start_full_send(AudioStream *stream, RtpProfile *profile, const char *remip,int remport, int payload,int jitt_comp, const char *infile, const char *outfile, MSSndCard *playcard, MSSndCard *captcard, bool_t use_ec) • 建立第二個session的設定(send端) • 產生soundread執行緒,進行傳送rtp封包 • ms_ticker_attach(stream->ticker,stream->soundread);
Implementing DCCP_2 4 • oRTP/rtpsession_inet.c • static ortp_socket_t create_and_bind_random(const char *localip, int *sock_family, int *port) • 呼叫使用沒有listen的socket函式,且port number為random (send端) • create_and_bind_send();
Implementing DCCP_2 5 • mediastream2/msrtp.c • static void sender_preprocess(MSFilter * f) • 建立connect • connect(rtp.socket, (struct sockaddr*)&rtp.rem_addr, rtp.rem_addrlen)
Implementing DCCP_2 6 • mediastream2/msrtp.c • static void receiver_preprocess(MSFilter * f) • 設定receive端的payload,並進行accept呼叫 • d->connfd=rtp_session_rtp_recv_accept();
Implementing DCCP_2 7 • oRTP/rtpsession_inet.c • int rtp_session_rtp_recv_accept (RtpSession * session) • 建立accept (receive端) • accept(sockfd,(struct sockaddr *) &remaddr,&addrlen)
Implementing DCCP_2 8 • oRTP/rtpsession_inet.c • static ortp_socket_t create_and_bind_send(const char *addr, int port, int *sock_family) • 建立socket並bind(send端) • 建立DCCP的預設使用值 SOCK_DCCP=6; SOL_DCCP=269; DCCP_SOCKOPT_PACKET_SIZE=1; DCCP_SOCKOPT_SERVICE=2; IPPROTO_DCCP=33; • socket(ai_family, SOCK_DCCP, IPPROTO_DCCP); • setsockopt(sock,SOL_DCCP,DCCP_SOCKOPT_PACKET_SIZE, (char*)&pkt_size,sizeof(pkt_size)); • setsockopt(sock,SOL_DCCP,DCCP_SOCKOPT_SERVICE,(char*)&pkt_size,sizeof(pkt_size)); • set_non_blocking_socket (sock); //將socket設定為non_blocking,由於DCCP為Connect-Oriented 必須使用accept(),所以不能non_blocking。
Implementing DCCP_3 1 • mediastream2/msrtp.c • static void receiver_process(MSFilter * f) • 進行接收rtp封包的process,修改加入accept參數(int connfd)。 • rtp_session_recvm_with_ts(session, timestamp,connfd)