00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "ortp/ortp.h"
00021 #include "utils.h"
00022 #include "ortp/rtpsession.h"
00023 #include "rtpsession_priv.h"
00024
00025
00026 #if defined(WIN32) || defined(_WIN32_WCE)
00027 #include "ortp-config-win32.h"
00028 #else
00029 #include "ortp-config.h"
00030 #endif
00031
00032 #ifdef HAVE_SYS_UIO_H
00033 #include <sys/uio.h>
00034 #define USE_SENDMSG 1
00035 #endif
00036
00037 #define can_connect(s) ( (s)->use_connect && !(s)->symmetric_rtp)
00038
00039 static bool_t try_connect(int fd, const struct sockaddr *dest, socklen_t addrlen){
00040 if (connect(fd,dest,addrlen)<0){
00041 ortp_warning("Could not connect() socket: %s",getSocketError());
00042 return FALSE;
00043 }
00044 return TRUE;
00045 }
00046
00047 static ortp_socket_t create_and_bind(const char *addr, int port, int *sock_family){
00048 int err;
00049 int optval = 1;
00050 ortp_socket_t sock=-1;
00051 #ifdef ORTP_INET6
00052 char num[8];
00053 struct addrinfo hints, *res0, *res;
00054 #else
00055 struct sockaddr_in saddr;
00056 #endif
00057
00058 #ifdef ORTP_INET6
00059
00060 memset(&hints, 0, sizeof(hints));
00061 hints.ai_family = PF_UNSPEC;
00062 hints.ai_socktype = SOCK_DGRAM;
00063 snprintf(num, sizeof(num), "%d",port);
00064 err = getaddrinfo(addr,num, &hints, &res0);
00065 if (err!=0) {
00066 ortp_warning ("Error in getaddrinfo on (addr=%s port=%i): %s", addr, port, gai_strerror(err));
00067 return -1;
00068 }
00069
00070 for (res = res0; res; res = res->ai_next) {
00071 sock = socket(res->ai_family, res->ai_socktype, 0);
00072 if (sock < 0)
00073 continue;
00074
00075 err = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
00076 (SOCKET_OPTION_VALUE)&optval, sizeof (optval));
00077 if (err < 0)
00078 {
00079 ortp_warning ("Fail to set rtp address reusable: %s.", getSocketError());
00080 }
00081
00082 *sock_family=res->ai_family;
00083 err = bind (sock, res->ai_addr, res->ai_addrlen);
00084 if (err != 0)
00085 {
00086 ortp_warning ("Fail to bind rtp socket to (addr=%s port=%i) : %s.", addr,port, getSocketError());
00087 close_socket (sock);
00088 sock=-1;
00089 continue;
00090 }
00091 #ifndef __hpux
00092 switch (res->ai_family)
00093 {
00094 case AF_INET:
00095 if (IN_MULTICAST(ntohl(((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr)))
00096 {
00097 struct ip_mreq mreq;
00098 mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *) res->ai_addr)->sin_addr.s_addr;
00099 mreq.imr_interface.s_addr = INADDR_ANY;
00100 err = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (SOCKET_OPTION_VALUE) &mreq, sizeof(mreq));
00101 if (err < 0)
00102 {
00103 ortp_warning ("Fail to join address group: %s.", getSocketError());
00104 close_socket (sock);
00105 sock=-1;
00106 continue;
00107 }
00108 }
00109 break;
00110 case AF_INET6:
00111 if (IN6_IS_ADDR_MULTICAST(&(((struct sockaddr_in6 *) res->ai_addr)->sin6_addr)))
00112 {
00113 struct ipv6_mreq mreq;
00114 mreq.ipv6mr_multiaddr = ((struct sockaddr_in6 *) res->ai_addr)->sin6_addr;
00115 mreq.ipv6mr_interface = 0;
00116 err = setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (SOCKET_OPTION_VALUE)&mreq, sizeof(mreq));
00117 if (err < 0)
00118 {
00119 ortp_warning ("Fail to join address group: %s.", getSocketError());
00120 close_socket (sock);
00121 sock=-1;
00122 continue;
00123 }
00124 }
00125 break;
00126 }
00127 #endif
00128 break;
00129 }
00130 freeaddrinfo(res0);
00131 #else
00132 saddr.sin_family = AF_INET;
00133 *sock_family=AF_INET;
00134 err = inet_aton (addr, &saddr.sin_addr);
00135 if (err < 0)
00136 {
00137 ortp_warning ("Error in socket address:%s.", getSocketError());
00138 return err;
00139 }
00140 saddr.sin_port = htons (port);
00141
00142 sock = socket (PF_INET, SOCK_DGRAM, 0);
00143
00144 if (sock<0) return -1;
00145
00146 err = setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
00147 (SOCKET_OPTION_VALUE)&optval, sizeof (optval));
00148 if (err < 0)
00149 {
00150 ortp_warning ("Fail to set rtp address reusable: %s.",getSocketError());
00151 }
00152
00153 err = bind (sock,
00154 (struct sockaddr *) &saddr,
00155 sizeof (saddr));
00156
00157 if (err != 0)
00158 {
00159 ortp_warning ("Fail to bind rtp socket to port %i: %s.", port, getSocketError());
00160 close_socket (sock);
00161 return -1;
00162 }
00163 #endif
00164 if (sock>=0)
00165 {
00166 #ifdef WIN32
00167
00168 int bufsize = 32768;
00169 err = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *)&bufsize, sizeof(bufsize));
00170 if (err == -1) {
00171 ortp_warning ("Fail to increase buffer size for socket (port %i): %s.", port, getSocketError());
00172 }
00173 bufsize = 32768;
00174 err = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&bufsize, sizeof(bufsize));
00175 if (err == -1) {
00176 ortp_warning ("Fail to increase buffer size for socket (port %i): %s.", port, getSocketError());
00177 }
00178 #endif
00179 set_non_blocking_socket (sock);
00180 }
00181 return sock;
00182 }
00183
00184 static ortp_socket_t create_and_bind_random(const char *localip, int *sock_family, int *port){
00185 int retry;
00186 ortp_socket_t sock = -1;
00187 for (retry=0;retry<100;retry++)
00188 {
00189 int localport;
00190 do
00191 {
00192 localport = (rand () + 5000) & 0xfffe;
00193 }
00194 while ((localport < 5000) || (localport > 0xffff));
00195 sock = create_and_bind(localip, localport, sock_family);
00196 if (sock>=0) {
00197 *port=localport;
00198 return sock;
00199 }
00200 }
00201 ortp_warning("create_and_bind_random: Could not find a random port for %s !",localip);
00202 return -1;
00203 }
00204
00220 int
00221 rtp_session_set_local_addr (RtpSession * session, const char * addr, int port)
00222 {
00223 ortp_socket_t sock;
00224 int sockfamily;
00225 if (session->rtp.socket>=0){
00226
00227 rtp_session_release_sockets(session);
00228 }
00229
00230 if (port>0)
00231 sock=create_and_bind(addr,port,&sockfamily);
00232 else
00233 sock=create_and_bind_random(addr,&sockfamily,&port);
00234 if (sock>=0){
00235 session->rtp.sockfamily=sockfamily;
00236 session->rtp.socket=sock;
00237 session->rtp.loc_port=port;
00238
00239 sock=create_and_bind(addr,port+1,&sockfamily);
00240 if (sock>=0){
00241 session->rtcp.sockfamily=sockfamily;
00242 session->rtcp.socket=sock;
00243 }else{
00244 ortp_warning("Could not create and bind rtcp socket.");
00245 }
00246
00247
00248 rtp_session_set_dscp( session, -1 );
00249 rtp_session_set_multicast_ttl( session, -1 );
00250 rtp_session_set_multicast_loopback( session, -1 );
00251
00252 return 0;
00253 }
00254 return -1;
00255 }
00256
00257
00268 int rtp_session_set_multicast_ttl(RtpSession *session, int ttl)
00269 {
00270 int retval;
00271
00272
00273 if (ttl>0) session->multicast_ttl = ttl;
00274
00275
00276 if (session->rtp.socket < 0) return 0;
00277
00278 switch (session->rtp.sockfamily) {
00279 case AF_INET: {
00280
00281 retval= setsockopt(session->rtp.socket, IPPROTO_IP, IP_MULTICAST_TTL,
00282 (SOCKET_OPTION_VALUE) &session->multicast_ttl, sizeof(session->multicast_ttl));
00283
00284 if (retval<0) break;
00285
00286 retval= setsockopt(session->rtcp.socket, IPPROTO_IP, IP_MULTICAST_TTL,
00287 (SOCKET_OPTION_VALUE) &session->multicast_ttl, sizeof(session->multicast_ttl));
00288
00289 } break;
00290
00291 case AF_INET6: {
00292
00293 retval= setsockopt(session->rtp.socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
00294 (SOCKET_OPTION_VALUE)&session->multicast_ttl, sizeof(session->multicast_ttl));
00295
00296 if (retval<0) break;
00297
00298 retval= setsockopt(session->rtcp.socket, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
00299 (SOCKET_OPTION_VALUE) &session->multicast_ttl, sizeof(session->multicast_ttl));
00300
00301 } break;
00302
00303 default:
00304 retval=-1;
00305 }
00306
00307 if (retval<0)
00308 ortp_warning("Failed to set multicast TTL on socket.");
00309
00310
00311 return retval;
00312 }
00313
00314
00322 int rtp_session_get_multicast_ttl(RtpSession *session)
00323 {
00324 return session->multicast_ttl;
00325 }
00326
00327
00338 int rtp_session_set_multicast_loopback(RtpSession *session, int yesno)
00339 {
00340 int retval;
00341
00342
00343 if (yesno==0) {
00344
00345 session->multicast_loopback = 0;
00346 } else if (yesno>0) {
00347
00348 session->multicast_loopback = 1;
00349 }
00350
00351
00352 if (session->rtp.socket < 0) return 0;
00353
00354 switch (session->rtp.sockfamily) {
00355 case AF_INET: {
00356
00357 retval= setsockopt(session->rtp.socket, IPPROTO_IP, IP_MULTICAST_LOOP,
00358 (SOCKET_OPTION_VALUE) &session->multicast_loopback, sizeof(session->multicast_loopback));
00359
00360 if (retval<0) break;
00361
00362 retval= setsockopt(session->rtcp.socket, IPPROTO_IP, IP_MULTICAST_LOOP,
00363 (SOCKET_OPTION_VALUE) &session->multicast_loopback, sizeof(session->multicast_loopback));
00364
00365 } break;
00366
00367 case AF_INET6: {
00368
00369 retval= setsockopt(session->rtp.socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
00370 (SOCKET_OPTION_VALUE) &session->multicast_loopback, sizeof(session->multicast_loopback));
00371
00372 if (retval<0) break;
00373
00374 retval= setsockopt(session->rtcp.socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP,
00375 (SOCKET_OPTION_VALUE) &session->multicast_loopback, sizeof(session->multicast_loopback));
00376
00377 } break;
00378
00379 default:
00380 retval=-1;
00381 }
00382
00383 if (retval<0)
00384 ortp_warning("Failed to set multicast loopback on socket.");
00385
00386
00387 return retval;
00388 }
00389
00390
00398 int rtp_session_get_multicast_loopback(RtpSession *session)
00399 {
00400 return session->multicast_loopback;
00401 }
00402
00413 int rtp_session_set_dscp(RtpSession *session, int dscp){
00414 int retval=0;
00415 int tos;
00416
00417
00418 if (dscp>=0) session->dscp = dscp;
00419
00420
00421 if (session->rtp.socket < 0) return 0;
00422
00423
00424 tos = (session->dscp << 2) & 0xFC;
00425 switch (session->rtp.sockfamily) {
00426 case AF_INET:
00427 retval = setsockopt(session->rtp.socket, IPPROTO_IP, IP_TOS, (SOCKET_OPTION_VALUE)&tos, sizeof(tos));
00428 break;
00429 #ifdef ORTP_INET6
00430 case AF_INET6:
00431 # ifdef IPV6_TCLASS
00432 retval = setsockopt(session->rtp.socket, IPPROTO_IPV6, IPV6_TCLASS,
00433 (SOCKET_OPTION_VALUE)&tos, sizeof(tos));
00434 # else
00435
00436 retval = setsockopt(session->rtp.socket, IPPROTO_IPV6, IP_TOS,
00437 (SOCKET_OPTION_VALUE)&tos, sizeof(tos));
00438 #endif
00439 break;
00440 #endif
00441 default:
00442 retval=-1;
00443 }
00444 if (retval<0)
00445 ortp_warning("Failed to set DSCP value on socket.");
00446
00447 return retval;
00448 }
00449
00450
00458 int rtp_session_get_dscp(const RtpSession *session)
00459 {
00460 return session->dscp;
00461 }
00462
00463
00474 int rtp_session_get_local_port(const RtpSession *session){
00475 return (session->rtp.loc_port>0) ? session->rtp.loc_port : -1;
00476 }
00477
00478
00479 static char * ortp_inet_ntoa(struct sockaddr *addr, int addrlen, char *dest, int destlen){
00480 #ifdef ORTP_INET6
00481 int err;
00482 dest[0]=0;
00483 err=getnameinfo(addr,addrlen,dest,destlen,NULL,0,NI_NUMERICHOST);
00484 if (err!=0){
00485 ortp_warning("getnameinfo error: %s",gai_strerror(err));
00486 }
00487 #else
00488 char *tmp=inet_ntoa(((struct sockaddr_in*)addr)->sin_addr);
00489 strncpy(dest,tmp,destlen);
00490 dest[destlen-1]='\0';
00491 #endif
00492 return dest;
00493 }
00494
00507 int
00508 rtp_session_set_remote_addr (RtpSession * session, const char * addr, int port)
00509 {
00510 return rtp_session_set_remote_addr_and_port (session, addr, port, port+1);
00511 }
00512
00527 int
00528 rtp_session_set_remote_addr_and_port (RtpSession * session, const char * addr, int rtp_port, int rtcp_port)
00529 {
00530 int err;
00531 #ifdef ORTP_INET6
00532 struct addrinfo hints, *res0, *res;
00533 char num[8];
00534 memset(&hints, 0, sizeof(hints));
00535 hints.ai_family = PF_UNSPEC;
00536 hints.ai_socktype = SOCK_DGRAM;
00537 snprintf(num, sizeof(num), "%d", rtp_port);
00538 err = getaddrinfo(addr, num, &hints, &res0);
00539 if (err) {
00540 ortp_warning ("Error in socket address: %s", gai_strerror(err));
00541 return -1;
00542 }
00543 #endif
00544 if (session->rtp.socket == -1){
00545
00546 ortp_message ("Setting random local addresses.");
00547 #ifdef ORTP_INET6
00548
00549 if (res0->ai_addr->sa_family==AF_INET6)
00550 err = rtp_session_set_local_addr (session, "::", -1);
00551 else err=rtp_session_set_local_addr (session, "0.0.0.0", -1);
00552 #else
00553 err = rtp_session_set_local_addr (session, "0.0.0.0", -1);
00554 #endif
00555 if (err<0) return -1;
00556 }
00557
00558 #ifdef ORTP_INET6
00559 err=1;
00560 for (res = res0; res; res = res->ai_next) {
00561
00562 if (res->ai_family==session->rtp.sockfamily ) {
00563 memcpy( &session->rtp.rem_addr, res->ai_addr, res->ai_addrlen);
00564 session->rtp.rem_addrlen=res->ai_addrlen;
00565 err=0;
00566 break;
00567 }
00568 }
00569 freeaddrinfo(res0);
00570 if (err) {
00571 ortp_warning("Could not set destination for RTP socket to %s:%i.",addr,rtp_port);
00572 return -1;
00573 }
00574
00575 memset(&hints, 0, sizeof(hints));
00576 hints.ai_family = PF_UNSPEC;
00577 hints.ai_socktype = SOCK_DGRAM;
00578 snprintf(num, sizeof(num), "%d", rtcp_port);
00579 err = getaddrinfo(addr, num, &hints, &res0);
00580 if (err) {
00581 ortp_warning ("Error: %s", gai_strerror(err));
00582 return err;
00583 }
00584 err=1;
00585 for (res = res0; res; res = res->ai_next) {
00586
00587 if (res->ai_family==session->rtp.sockfamily ) {
00588 err=0;
00589 memcpy( &session->rtcp.rem_addr, res->ai_addr, res->ai_addrlen);
00590 session->rtcp.rem_addrlen=res->ai_addrlen;
00591 break;
00592 }
00593 }
00594 freeaddrinfo(res0);
00595 if (err) {
00596 ortp_warning("Could not set destination for RCTP socket to %s:%i.",addr,rtcp_port);
00597 return -1;
00598 }
00599 #else
00600 session->rtp.rem_addrlen=sizeof(session->rtp.rem_addr);
00601 session->rtp.rem_addr.sin_family = AF_INET;
00602
00603 err = inet_aton (addr, &session->rtp.rem_addr.sin_addr);
00604 if (err < 0)
00605 {
00606 ortp_warning ("Error in socket address:%s.", getSocketError());
00607 return err;
00608 }
00609 session->rtp.rem_addr.sin_port = htons (rtp_port);
00610
00611 memcpy (&session->rtcp.rem_addr, &session->rtp.rem_addr,
00612 sizeof (struct sockaddr_in));
00613 session->rtcp.rem_addr.sin_port = htons (rtcp_port);
00614 session->rtcp.rem_addrlen=sizeof(session->rtcp.rem_addr);
00615 #endif
00616 if (can_connect(session)){
00617 if (try_connect(session->rtp.socket,(struct sockaddr*)&session->rtp.rem_addr,session->rtp.rem_addrlen))
00618 session->flags|=RTP_SOCKET_CONNECTED;
00619 if (session->rtcp.socket>=0){
00620 if (try_connect(session->rtcp.socket,(struct sockaddr*)&session->rtcp.rem_addr,session->rtcp.rem_addrlen))
00621 session->flags|=RTCP_SOCKET_CONNECTED;
00622 }
00623 }else if (session->flags & RTP_SOCKET_CONNECTED){
00624
00625
00626 struct sockaddr sa;
00627 sa.sa_family=AF_UNSPEC;
00628 if (connect(session->rtp.socket,&sa,sizeof(sa))<0){
00629 ortp_error("Cannot dissolve connect() association for rtp socket: %s", getSocketError());
00630 }
00631 if (connect(session->rtcp.socket,&sa,sizeof(sa))<0){
00632 ortp_error("Cannot dissolve connect() association for rtcp socket: %s", getSocketError());
00633 }
00634 session->flags&=~RTP_SOCKET_CONNECTED;
00635 session->flags&=~RTCP_SOCKET_CONNECTED;
00636 }
00637 return 0;
00638 }
00639
00640 void rtp_session_set_sockets(RtpSession *session, int rtpfd, int rtcpfd)
00641 {
00642 if (rtpfd>=0) set_non_blocking_socket(rtpfd);
00643 if (rtcpfd>=0) set_non_blocking_socket(rtcpfd);
00644 session->rtp.socket=rtpfd;
00645 session->rtcp.socket=rtcpfd;
00646 if (rtpfd>=0 || rtcpfd>=0 )
00647 session->flags|=(RTP_SESSION_USING_EXT_SOCKETS|RTP_SOCKET_CONNECTED|RTCP_SOCKET_CONNECTED);
00648 else session->flags&=~(RTP_SESSION_USING_EXT_SOCKETS|RTP_SOCKET_CONNECTED|RTCP_SOCKET_CONNECTED);
00649 }
00650
00651 void rtp_session_set_transports(RtpSession *session, struct _RtpTransport *rtptr, struct _RtpTransport *rtcptr)
00652 {
00653 session->rtp.tr = rtptr;
00654 session->rtcp.tr = rtcptr;
00655 if (rtptr)
00656 rtptr->session=session;
00657 if (rtcptr)
00658 rtcptr->session=session;
00659
00660 if (rtptr || rtcptr )
00661 session->flags|=(RTP_SESSION_USING_TRANSPORT);
00662 else session->flags&=~(RTP_SESSION_USING_TRANSPORT);
00663 }
00664
00665
00666
00677 void rtp_session_flush_sockets(RtpSession *session){
00678 unsigned char trash[4096];
00679 #ifdef ORTP_INET6
00680 struct sockaddr_storage from;
00681 #else
00682 struct sockaddr from;
00683 #endif
00684 socklen_t fromlen=sizeof(from);
00685 if (rtp_session_using_transport(session, rtp))
00686 {
00687 mblk_t *trashmp=esballoc(trash,sizeof(trash),0,NULL);
00688
00689 while (session->rtp.tr->t_recvfrom(session->rtp.tr,trashmp,0,(struct sockaddr *)&from,&fromlen)>0){};
00690
00691 if (session->rtcp.tr)
00692 while (session->rtcp.tr->t_recvfrom(session->rtcp.tr,trashmp,0,(struct sockaddr *)&from,&fromlen)>0){};
00693 freemsg(trashmp);
00694 return;
00695 }
00696
00697 if (session->rtp.socket>=0){
00698 while (recvfrom(session->rtp.socket,trash,sizeof(trash),0,(struct sockaddr *)&from,&fromlen)>0){};
00699 }
00700 if (session->rtcp.socket>=0){
00701 while (recvfrom(session->rtcp.socket,trash,sizeof(trash),0,(struct sockaddr*)&from,&fromlen)>0){};
00702 }
00703 }
00704
00705
00706 #ifdef USE_SENDMSG
00707 #define MAX_IOV 30
00708 static int rtp_sendmsg(int sock,mblk_t *m, struct sockaddr *rem_addr, int addr_len){
00709 int error;
00710 struct msghdr msg;
00711 struct iovec iov[MAX_IOV];
00712 int iovlen;
00713 for(iovlen=0; iovlen<MAX_IOV && m!=NULL; m=m->b_cont,iovlen++){
00714 iov[iovlen].iov_base=m->b_rptr;
00715 iov[iovlen].iov_len=m->b_wptr-m->b_rptr;
00716 }
00717 if (iovlen==MAX_IOV){
00718 ortp_error("Too long msgb, didn't fit into iov, end discarded.");
00719 }
00720 msg.msg_name=(void*)rem_addr;
00721 msg.msg_namelen=addr_len;
00722 msg.msg_iov=&iov[0];
00723 msg.msg_iovlen=iovlen;
00724 msg.msg_control=NULL;
00725 msg.msg_controllen=0;
00726 msg.msg_flags=0;
00727 error=sendmsg(sock,&msg,0);
00728 return error;
00729 }
00730 #endif
00731
00732 #define IP_UDP_OVERHEAD (20+8)
00733
00734 static void update_sent_bytes(RtpSession*s, int nbytes){
00735 if (s->rtp.sent_bytes==0){
00736 gettimeofday(&s->rtp.send_bw_start,NULL);
00737 }
00738 s->rtp.sent_bytes+=nbytes+IP_UDP_OVERHEAD;
00739 }
00740
00741 static void update_recv_bytes(RtpSession*s, int nbytes){
00742 if (s->rtp.recv_bytes==0){
00743 gettimeofday(&s->rtp.recv_bw_start,NULL);
00744 }
00745 s->rtp.recv_bytes+=nbytes+IP_UDP_OVERHEAD;
00746 }
00747
00748 int
00749 rtp_session_rtp_send (RtpSession * session, mblk_t * m)
00750 {
00751 int error;
00752 int i;
00753 rtp_header_t *hdr;
00754 struct sockaddr *destaddr=(struct sockaddr*)&session->rtp.rem_addr;
00755 socklen_t destlen=session->rtp.rem_addrlen;
00756 ortp_socket_t sockfd=session->rtp.socket;
00757
00758 hdr = (rtp_header_t *) m->b_rptr;
00759
00760 hdr->ssrc = htonl (hdr->ssrc);
00761 hdr->timestamp = htonl (hdr->timestamp);
00762 hdr->seq_number = htons (hdr->seq_number);
00763 for (i = 0; i < hdr->cc; i++)
00764 hdr->csrc[i] = htonl (hdr->csrc[i]);
00765
00766 if (session->flags & RTP_SOCKET_CONNECTED) {
00767 destaddr=NULL;
00768 destlen=0;
00769 }
00770
00771 if (rtp_session_using_transport(session, rtp)){
00772 error = (session->rtp.tr->t_sendto) (session->rtp.tr,m,0,destaddr,destlen);
00773 }else{
00774 #ifdef USE_SENDMSG
00775 error=rtp_sendmsg(sockfd,m,destaddr,destlen);
00776 #else
00777 if (m->b_cont!=NULL)
00778 msgpullup(m,-1);
00779 error = sendto (sockfd, m->b_rptr, (int) (m->b_wptr - m->b_rptr),
00780 0,destaddr,destlen);
00781 #endif
00782 }
00783 if (error < 0){
00784 if (session->on_network_error.count>0){
00785 rtp_signal_table_emit3(&session->on_network_error,(long)"Error sending RTP packet",INT_TO_POINTER(getSocketErrorCode()));
00786 }else ortp_warning ("Error sending rtp packet: %s ; socket=%i", getSocketError(), sockfd);
00787 session->rtp.send_errno=getSocketErrorCode();
00788 }else{
00789 update_sent_bytes(session,error);
00790 }
00791 freemsg (m);
00792 return error;
00793 }
00794
00795 int
00796 rtp_session_rtcp_send (RtpSession * session, mblk_t * m)
00797 {
00798 int error=0;
00799 ortp_socket_t sockfd=session->rtcp.socket;
00800 struct sockaddr *destaddr=(struct sockaddr*)&session->rtcp.rem_addr;
00801 socklen_t destlen=session->rtcp.rem_addrlen;
00802 bool_t using_connected_socket=(session->flags & RTCP_SOCKET_CONNECTED)!=0;
00803
00804 if (using_connected_socket) {
00805 destaddr=NULL;
00806 destlen=0;
00807 }
00808
00809 if (session->rtcp.enabled &&
00810 ( (sockfd>=0 && (session->rtcp.rem_addrlen>0 ||using_connected_socket))
00811 || rtp_session_using_transport(session, rtcp) ) ){
00812 if (rtp_session_using_transport(session, rtcp)){
00813 error = (session->rtcp.tr->t_sendto) (session->rtcp.tr, m, 0,
00814 destaddr, destlen);
00815 }
00816 else{
00817 #ifdef USE_SENDMSG
00818 error=rtp_sendmsg(sockfd,m,destaddr, destlen);
00819 #else
00820 if (m->b_cont!=NULL){
00821 msgpullup(m,-1);
00822 }
00823 error = sendto (sockfd, m->b_rptr,
00824 (int) (m->b_wptr - m->b_rptr), 0,
00825 destaddr, destlen);
00826 #endif
00827 }
00828 if (error < 0){
00829 char host[65];
00830 if (session->on_network_error.count>0){
00831 rtp_signal_table_emit3(&session->on_network_error,(long)"Error sending RTCP packet",INT_TO_POINTER(getSocketErrorCode()));
00832 }else ortp_warning ("Error sending rtcp packet: %s ; socket=%i; addr=%s", getSocketError(), session->rtcp.socket, ortp_inet_ntoa((struct sockaddr*)&session->rtcp.rem_addr,session->rtcp.rem_addrlen,host,sizeof(host)) );
00833 }
00834 }else ortp_message("Not sending rtcp report: sockfd=%i, rem_addrlen=%i, connected=%i",sockfd,session->rtcp.rem_addrlen,using_connected_socket);
00835 freemsg (m);
00836 return error;
00837 }
00838
00839 int
00840 rtp_session_rtp_recv (RtpSession * session, uint32_t user_ts)
00841 {
00842 int error;
00843 ortp_socket_t sockfd=session->rtp.socket;
00844 #ifdef ORTP_INET6
00845 struct sockaddr_storage remaddr;
00846 #else
00847 struct sockaddr remaddr;
00848 #endif
00849 socklen_t addrlen = sizeof (remaddr);
00850 mblk_t *mp;
00851
00852 if ((sockfd<0) && !rtp_session_using_transport(session, rtp)) return -1;
00853
00854 while (1)
00855 {
00856 int bufsz;
00857 bool_t sock_connected=!!(session->flags & RTP_SOCKET_CONNECTED);
00858
00859 if (session->rtp.cached_mp==NULL)
00860 session->rtp.cached_mp = allocb (session->recv_buf_size, 0);
00861 mp=session->rtp.cached_mp;
00862 bufsz=(int) (mp->b_datap->db_lim - mp->b_datap->db_base);
00863 if (sock_connected){
00864 error=recv(sockfd,mp->b_wptr,bufsz,0);
00865 }else if (rtp_session_using_transport(session, rtp))
00866 error = (session->rtp.tr->t_recvfrom)(session->rtp.tr, mp, 0,
00867 (struct sockaddr *) &remaddr,
00868 &addrlen);
00869 else error = recvfrom(sockfd, mp->b_wptr,
00870 bufsz, 0,
00871 (struct sockaddr *) &remaddr,
00872 &addrlen);
00873 if (error > 0){
00874 if (session->symmetric_rtp && !sock_connected){
00875
00876 memcpy(&session->rtp.rem_addr,&remaddr,addrlen);
00877 session->rtp.rem_addrlen=addrlen;
00878 if (session->use_connect){
00879 if (try_connect(sockfd,(struct sockaddr*)&remaddr,addrlen))
00880 session->flags|=RTP_SOCKET_CONNECTED;
00881 }
00882 }
00883
00884 mp->b_wptr+=error;
00885 rtp_session_rtp_parse (session, mp, user_ts + session->rtp.hwrcv_diff_ts, (struct sockaddr*)&remaddr,addrlen);
00886 session->rtp.cached_mp=NULL;
00887
00888 update_recv_bytes(session,error);
00889 }
00890 else
00891 {
00892 int errnum=getSocketErrorCode();
00893
00894 if (error == 0)
00895 {
00896 ortp_warning
00897 ("rtp_recv: strange... recv() returned zero.");
00898 }
00899 else if (!is_would_block_error(errnum))
00900 {
00901 if (session->on_network_error.count>0){
00902 rtp_signal_table_emit3(&session->on_network_error,(long)"Error receiving RTP packet",INT_TO_POINTER(getSocketErrorCode()));
00903 }else ortp_warning("Error receiving RTP packet: %s.",getSocketError());
00904 }
00905
00906 return -1;
00907 }
00908 }
00909 return error;
00910 }
00911
00912 void rtp_session_notify_inc_rtcp(RtpSession *session, mblk_t *m){
00913 if (session->eventqs!=NULL){
00914 OrtpEvent *ev=ortp_event_new(ORTP_EVENT_RTCP_PACKET_RECEIVED);
00915 OrtpEventData *d=ortp_event_get_data(ev);
00916 d->packet=m;
00917 rtp_session_dispatch_event(session,ev);
00918 }
00919 else
00920 freemsg(m);
00921 }
00922
00923 int
00924 rtp_session_rtcp_recv (RtpSession * session)
00925 {
00926 int error;
00927 #ifdef ORTP_INET6
00928 struct sockaddr_storage remaddr;
00929 #else
00930 struct sockaddr remaddr;
00931 #endif
00932 socklen_t addrlen=0;
00933 mblk_t *mp;
00934
00935 if (session->rtcp.socket<0 && !rtp_session_using_transport(session, rtcp)) return -1;
00936
00937
00938 while (1)
00939 {
00940 bool_t sock_connected=!!(session->flags & RTCP_SOCKET_CONNECTED);
00941 if (session->rtcp.cached_mp==NULL)
00942 session->rtcp.cached_mp = allocb (RTCP_MAX_RECV_BUFSIZE, 0);
00943
00944 mp=session->rtcp.cached_mp;
00945 if (sock_connected){
00946 error=recv(session->rtcp.socket,mp->b_wptr,RTCP_MAX_RECV_BUFSIZE,0);
00947 }else {
00948 addrlen=sizeof (remaddr);
00949
00950 if (rtp_session_using_transport(session, rtcp))
00951 error=(session->rtcp.tr->t_recvfrom)(session->rtcp.tr, mp, 0,
00952 (struct sockaddr *) &remaddr,
00953 &addrlen);
00954 else
00955 error=recvfrom (session->rtcp.socket, mp->b_wptr,
00956 RTCP_MAX_RECV_BUFSIZE, 0,
00957 (struct sockaddr *) &remaddr,
00958 &addrlen);
00959 }
00960 if (error > 0)
00961 {
00962 mp->b_wptr += error;
00963
00964 {
00965 rtp_session_notify_inc_rtcp(session,mp);
00966 }
00967 session->rtcp.cached_mp=NULL;
00968 if (session->symmetric_rtp && !sock_connected){
00969
00970 memcpy(&session->rtcp.rem_addr,&remaddr,addrlen);
00971 session->rtcp.rem_addrlen=addrlen;
00972 if (session->use_connect){
00973 if (try_connect(session->rtcp.socket,(struct sockaddr*)&remaddr,addrlen))
00974 session->flags|=RTCP_SOCKET_CONNECTED;
00975 }
00976 }
00977 }
00978 else
00979 {
00980 int errnum=getSocketErrorCode();
00981
00982 if (error == 0)
00983 {
00984 ortp_warning
00985 ("rtcp_recv: strange... recv() returned zero.");
00986 }
00987 else if (!is_would_block_error(errnum))
00988 {
00989 if (session->on_network_error.count>0){
00990 rtp_signal_table_emit3(&session->on_network_error,(long)"Error receiving RTCP packet",INT_TO_POINTER(errnum));
00991 }else ortp_warning("Error receiving RTCP packet: %s.",getSocketError());
00992 session->rtp.recv_errno=errnum;
00993 }
00994
00995 return -1;
00996 }
00997 }
00998 return error;
00999 }
01000