00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00027 #include "rtp.h"
00028 #include "bufferpool.h"
00029 #include "utils.h"
00030
00037 rtp_ssrc *rtp_active_ssrc_queue(rtp_session * rtp_sess_head)
00038 {
00039 rtp_session *rtp_sess;
00040
00041 for (rtp_sess = rtp_sess_head;
00042 rtp_sess && !rtp_sess->active_ssrc_queue;
00043 rtp_sess = rtp_sess->next);
00044
00045 return rtp_sess ? rtp_sess->active_ssrc_queue : NULL;
00046 }
00047
00053 rtp_ssrc *rtp_next_active_ssrc(rtp_ssrc * ssrc)
00054 {
00055 rtp_session *rtp_sess;
00056
00057 if (!ssrc)
00058 return NULL;
00059
00060 if (ssrc->next_active)
00061 return ssrc->next_active;
00062
00063 for (rtp_sess = ssrc->rtp_sess->next; rtp_sess;
00064 rtp_sess = rtp_sess->next)
00065 if (rtp_sess->active_ssrc_queue)
00066 return rtp_sess->active_ssrc_queue;
00067
00068 return NULL;
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 static int rtcp_to_connect(rtp_ssrc * stm_src, nms_addr * remoteaddr, in_port_t port)
00080 {
00081 char addr[128];
00082 char port_str[16];
00083 struct sockaddr_storage rtcp_to_addr_s;
00084 nms_sockaddr rtcp_to_addr =
00085 { (struct sockaddr *) &rtcp_to_addr_s, sizeof(rtcp_to_addr_s) };
00086
00087 if (port > 0)
00088
00089 snprintf(port_str, sizeof(port_str), "%d", port);
00090 else
00091 return nms_printf(NMSML_ERR,
00092 "RTCP: Cannot connect to port (%d)\n", port);
00093
00094 if (!nms_addr_ntop(remoteaddr, addr, sizeof(addr))) {
00095 nms_printf(NMSML_WARN,
00096 "RTP: Cannot get address from source\n");
00097 stm_src->no_rtcp = 1;
00098 return 1;
00099 } else
00100 nms_printf(NMSML_DBG2, "RTCP to host=%s\n", addr);
00101
00102
00103
00104
00105
00106
00107
00108 getsockname(stm_src->rtp_sess->transport.RTCP.sock.fd, rtcp_to_addr.addr,
00109 &rtcp_to_addr.addr_len);
00110 nms_sockaddr_dup(&stm_src->rtcp_to, &rtcp_to_addr);
00111
00112 return 0;
00113 }
00114
00125 int rtp_ssrc_init(rtp_session * rtp_sess, rtp_ssrc ** stm_src, uint32_t ssrc,
00126 nms_sockaddr * recfrom, enum rtp_protos proto_type)
00127 {
00128 int addrcmp_err;
00129 nms_addr nms_address;
00130
00131 if (((*stm_src) = (rtp_ssrc *) calloc(1, sizeof(rtp_ssrc))) == NULL)
00132 return -nms_printf(NMSML_FATAL, "Cannot allocate memory\n");
00133
00134 (*stm_src)->po = calloc(1, sizeof(playout_buff));
00135
00136 (*stm_src)->next = rtp_sess->ssrc_queue;
00137 rtp_sess->ssrc_queue = *stm_src;
00138
00139 (*stm_src)->ssrc = ssrc;
00140 (*stm_src)->no_rtcp = 0;
00141 (*stm_src)->rtp_sess = rtp_sess;
00142
00143 if (proto_type == RTP) {
00144 nms_sockaddr_dup(&(*stm_src)->rtp_from, recfrom);
00145 nms_printf(NMSML_DBG2, "RTP/rtp_ssrc_init: proto RTP\n");
00146 } else if (proto_type == RTCP) {
00147 nms_sockaddr_dup(&(*stm_src)->rtcp_from, recfrom);
00148 nms_printf(NMSML_DBG2, "RTP/rtp_ssrc_init: proto RTCP\n");
00149 }
00150
00151 if (rtp_sess->transport.type != UDP) {
00152
00153
00154 return 0;
00155 }
00156
00157 if (sockaddr_get_nms_addr(recfrom->addr, &nms_address))
00158 return -nms_printf(NMSML_ERR,
00159 "Address of received packet not valid\n");
00160 if (!
00161 (addrcmp_err =
00162 nms_addr_cmp(&nms_address, &rtp_sess->transport.RTP.u.udp.srcaddr))) {
00163
00164
00165
00166 if (rtcp_to_connect
00167 (*stm_src, &rtp_sess->transport.RTP.u.udp.srcaddr,
00168 (rtp_sess->transport).RTCP.sock.remote_port) < 0)
00169 return -1;
00170 nms_printf(NMSML_DBG2, "RTP/rtp_ssrc_init: from RTSP\n");
00171
00172 } else if (proto_type == RTCP) {
00173
00174
00175
00176 if (rtcp_to_connect
00177 (*stm_src, &nms_address,
00178 (rtp_sess->transport).RTCP.sock.remote_port) < 0)
00179 return -1;
00180 nms_printf(NMSML_DBG2, "RTP/rtp_ssrc_init: from RTP\n");
00181 } else {
00182 switch (addrcmp_err) {
00183 case WSOCK_ERRFAMILY:
00184 nms_printf(NMSML_DBG2, "WSOCK_ERRFAMILY (%d!=%d)\n",
00185 nms_address.family,
00186 rtp_sess->transport.RTP.u.udp.srcaddr.family);
00187 break;
00188 case WSOCK_ERRADDR:
00189 nms_printf(NMSML_DBG2, "WSOCK_ERRADDR\n");
00190 break;
00191 case WSOCK_ERRFAMILYUNKNOWN:
00192 nms_printf(NMSML_DBG2, "WSOCK_ERRFAMILYUNKNOWN\n");
00193 break;
00194 }
00195 nms_printf(NMSML_DBG2,
00196 "RTP/rtp_ssrc_init: rtcp_to NOT set!!!\n");
00197
00198 }
00199
00200 return 0;
00201 }
00202
00214 int rtp_ssrc_check(rtp_session * rtp_sess, uint32_t ssrc, rtp_ssrc ** stm_src,
00215 nms_sockaddr * recfrom, enum rtp_protos proto_type)
00216 {
00217 struct rtp_conflict *stm_conf = rtp_sess->conf_queue;
00218 struct sockaddr_storage sockaddr;
00219 nms_sockaddr sock =
00220 { (struct sockaddr *) &sockaddr, sizeof(sockaddr) };
00221 int local_collision;
00222
00223
00224 local_collision = (rtp_sess->local_ssrc == ssrc) ? SSRC_COLLISION : 0;
00225 pthread_mutex_lock(&rtp_sess->syn);
00226 pthread_mutex_unlock(&rtp_sess->syn);
00227 for (*stm_src = rtp_sess->ssrc_queue;
00228 !local_collision && *stm_src && ((*stm_src)->ssrc != ssrc);
00229 *stm_src = (*stm_src)->next);
00230 if (!*stm_src && !local_collision) {
00231
00232 pthread_mutex_lock(&rtp_sess->syn);
00233 nms_printf(NMSML_DBG3, "new SSRC\n");
00234 if (rtp_ssrc_init(rtp_sess, stm_src, ssrc, recfrom, proto_type)
00235 < 0) {
00236 pthread_mutex_unlock(&rtp_sess->syn);
00237 return -nms_printf(NMSML_ERR,
00238 "Error while setting new Stream Source\n");
00239 }
00240
00241 poinit((*stm_src)->po, rtp_sess->bp);
00242 pthread_mutex_unlock(&rtp_sess->syn);
00243 return SSRC_NEW;
00244 } else {
00245 if (local_collision) {
00246
00247 if (proto_type == RTP)
00248 getsockname(rtp_sess->transport.RTP.sock.fd, sock.addr,
00249 &sock.addr_len);
00250 else
00251 getsockname(rtp_sess->transport.RTCP.sock.fd, sock.addr,
00252 &sock.addr_len);
00253
00254 } else if (proto_type == RTP) {
00255
00256 if (!(*stm_src)->rtp_from.addr) {
00257 nms_sockaddr_dup(&(*stm_src)->rtp_from, recfrom);
00258 nms_printf(NMSML_DBG3, "new SSRC for RTP\n");
00259 local_collision = SSRC_RTPNEW;
00260 }
00261 sock.addr = (*stm_src)->rtp_from.addr;
00262 sock.addr_len = (*stm_src)->rtp_from.addr_len;
00263
00264 } else {
00265
00266
00267 if (!(*stm_src)->rtcp_from.addr) {
00268 nms_sockaddr_dup(&(*stm_src)->rtcp_from, recfrom);
00269 nms_printf(NMSML_DBG3, "new SSRC for RTCP\n");
00270 local_collision = SSRC_RTCPNEW;
00271 }
00272 sock.addr = (*stm_src)->rtcp_from.addr;
00273 sock.addr_len = (*stm_src)->rtcp_from.addr_len;
00274
00275 if (rtp_sess->transport.type != UDP)
00276 return local_collision;
00277
00278 if (!(*stm_src)->rtcp_to.addr) {
00279 nms_addr nms_address;
00280
00281 if (sockaddr_get_nms_addr(recfrom->addr, &nms_address))
00282 return -nms_printf(NMSML_ERR,
00283 "Invalid address for received packet\n");
00284
00285
00286 if (rtcp_to_connect
00287 (*stm_src, &nms_address,
00288 (rtp_sess->transport).RTCP.sock.remote_port) < 0)
00289 return -1;
00290 }
00291 }
00292
00293 if ((rtp_sess->transport.type == UDP) && sockaddr_cmp
00294 (sock.addr, sock.addr_len, recfrom->addr,
00295 recfrom->addr_len)) {
00296 nms_printf(NMSML_ERR,
00297 "An identifier collision or a loop is indicated\n");
00298
00299
00300
00301 if (ssrc != rtp_sess->local_ssrc) {
00302
00303 nms_printf(NMSML_VERB,
00304 "Warning! An identifier collision or a loop is indicated.\n");
00305 return SSRC_COLLISION;
00306 }
00307
00308
00309
00310 else {
00311 while (stm_conf
00312 && sockaddr_cmp(stm_conf->transaddr.addr,
00313 stm_conf->transaddr.
00314 addr_len, recfrom->addr,
00315 recfrom->addr_len))
00316 stm_conf = stm_conf->next;
00317
00318 if (stm_conf) {
00319
00320
00321
00322 stm_conf->time = time(NULL);
00323 return SSRC_COLLISION;
00324 } else {
00325
00326
00327
00328 nms_printf(NMSML_VERB,
00329 "SSRC collision detected: getting new!\n");
00330
00331
00332
00333
00334
00335
00336 rtp_sess->local_ssrc = random32(0);
00337 rtp_sess->transport.ssrc =
00338 rtp_sess->local_ssrc;
00339
00340
00341 if ((stm_conf = (struct rtp_conflict *)
00342 malloc(sizeof
00343 (struct rtp_conflict))) ==
00344 NULL)
00345 return -nms_printf(NMSML_FATAL,
00346 "Cannot allocate memory!\n");
00347
00348
00349 pthread_mutex_lock(&rtp_sess->syn);
00350 if (rtp_ssrc_init
00351 (rtp_sess, stm_src, ssrc, recfrom,
00352 proto_type) < 0) {
00353 pthread_mutex_unlock
00354 (&rtp_sess->syn);
00355 return -nms_printf(NMSML_ERR,
00356 "Error while setting new Stream Source\n");
00357 }
00358 poinit((*stm_src)->po, rtp_sess->bp);
00359 pthread_mutex_unlock(&rtp_sess->syn);
00360
00361
00362 nms_sockaddr_dup(&stm_conf->transaddr,
00363 &sock);
00364 stm_conf->time = time(NULL);
00365 stm_conf->next = rtp_sess->conf_queue;
00366 rtp_sess->conf_queue = stm_conf;
00367 }
00368
00369 }
00370 }
00371 }
00372
00373 return local_collision;
00374 }