static int setup_dtls_srtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media) { struct ast_rtp_engine_dtls *dtls; if (!session->endpoint->media.rtp.dtls_cfg.enabled || !session_media->rtp) { return -1; } dtls = ast_rtp_instance_get_dtls(session_media->rtp); if (!dtls) { return -1; } session->endpoint->media.rtp.dtls_cfg.suite = ((session->endpoint->media.rtp.srtp_tag_32) ? AST_AES_CM_128_HMAC_SHA1_32 : AST_AES_CM_128_HMAC_SHA1_80); if (dtls->set_configuration(session_media->rtp, &session->endpoint->media.rtp.dtls_cfg)) { ast_log(LOG_ERROR, "Attempted to set an invalid DTLS-SRTP configuration on RTP instance '%p'\n", session_media->rtp); return -1; } if (setup_srtp(session_media)) { return -1; } return 0; }
static int setup_sdes_srtp(struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream) { int i; for (i = 0; i < stream->attr_count; i++) { pjmedia_sdp_attr *attr; RAII_VAR(char *, crypto_str, NULL, ast_free); /* check the stream for the required crypto attribute */ attr = stream->attr[i]; if (pj_strcmp2(&attr->name, "crypto")) { continue; } crypto_str = ast_strndup(attr->value.ptr, attr->value.slen); if (!crypto_str) { return -1; } if (setup_srtp(session_media)) { return -1; } if (!ast_sdp_crypto_process(session_media->rtp, session_media->srtp, crypto_str)) { /* found a valid crypto attribute */ return 0; } ast_debug(1, "Ignoring crypto offer with unsupported parameters: %s\n", crypto_str); } /* no usable crypto attributes found */ return -1; }
static int alloc(struct menc_media **stp, struct menc_sess *sess, struct rtp_sock *rtp, int proto, void *rtpsock, void *rtcpsock, struct sdp_media *sdpm) { struct menc_st *st; const char *rattr = NULL; int layer = 10; /* above zero */ int err = 0; bool mux = (rtpsock == rtcpsock); (void)sess; (void)rtp; if (!stp || !sdpm) return EINVAL; if (proto != IPPROTO_UDP) return EPROTONOSUPPORT; st = (struct menc_st *)*stp; if (!st) { st = mem_zalloc(sizeof(*st), destructor); if (!st) return ENOMEM; st->sdpm = mem_ref(sdpm); err = sdp_media_set_alt_protos(st->sdpm, 4, "RTP/AVP", "RTP/AVPF", "RTP/SAVP", "RTP/SAVPF"); if (err) goto out; if (rtpsock) { st->rtpsock = mem_ref(rtpsock); err |= udp_register_helper(&st->uh_rtp, rtpsock, layer, send_handler, recv_handler, st); } if (rtcpsock && !mux) { st->rtcpsock = mem_ref(rtcpsock); err |= udp_register_helper(&st->uh_rtcp, rtcpsock, layer, send_handler, recv_handler, st); } if (err) goto out; /* set our preferred crypto-suite */ err |= str_dup(&st->crypto_suite, aes_cm_128_hmac_sha1_80); if (err) goto out; err = setup_srtp(st); if (err) goto out; } /* SDP handling */ if (sdp_media_rattr(st->sdpm, "crypto")) { rattr = sdp_media_rattr_apply(st->sdpm, "crypto", sdp_attr_handler, st); if (!rattr) { DEBUG_WARNING("no valid a=crypto attribute from" " remote peer\n"); } } if (!rattr) err = sdp_enc(st, sdpm, 0, st->crypto_suite); out: if (err) mem_deref(st); else *stp = (struct menc_media *)st; return err; }