static void insert_candidate(struct sdp_chopper *chop, struct packet_stream *ps, unsigned int component, unsigned int type_pref, unsigned int local_pref, enum ice_candidate_type type, struct interface_address *ifa) { unsigned long priority; priority = ice_priority_pref(type_pref, local_pref, component); chopper_append_c(chop, "a=candidate:"); chopper_append_str(chop, &ifa->ice_foundation); chopper_append_printf(chop, " %u UDP %lu ", component, priority); insert_ice_address(chop, ps, ifa); chopper_append_c(chop, " typ "); chopper_append_c(chop, ice_candidate_type_str(type)); /* raddr and rport are required for non-host candidates: rfc5245 section-15.1 */ if(type != ICT_HOST) insert_raddr_rport(chop, ps, ifa); chopper_append_c(chop, "\r\n"); }
static void insert_candidate(struct sdp_chopper *chop, struct stream_fd *sfd, unsigned int type_pref, unsigned int local_pref, enum ice_candidate_type type) { unsigned long priority; struct packet_stream *ps = sfd->stream; const struct local_intf *ifa = sfd->local_intf; if (local_pref == -1) local_pref = ifa->unique_id; priority = ice_priority_pref(type_pref, local_pref, ps->component); chopper_append_c(chop, "a=candidate:"); chopper_append_str(chop, &ifa->ice_foundation); chopper_append_printf(chop, " %u UDP %lu ", ps->component, priority); insert_ice_address(chop, sfd); chopper_append_c(chop, " typ "); chopper_append_c(chop, ice_candidate_type_str(type)); /* raddr and rport are required for non-host candidates: rfc5245 section-15.1 */ if(type != ICT_HOST) insert_raddr_rport(chop, ps, ifa); chopper_append_c(chop, "\r\n"); }
/* called with call->master_lock held in W */ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call_monologue *monologue, struct sdp_ng_flags *flags) { struct sdp_session *session; struct sdp_media *sdp_media; GList *l, *k, *m, *j; int media_index, sess_conn; struct call_media *call_media; struct packet_stream *ps, *ps_rtcp; m = monologue->medias.head; for (l = sessions->head; l; l = l->next) { session = l->data; if (!m) goto error; call_media = m->data; if (call_media->index != 1) goto error; j = call_media->streams.head; if (!j) goto error; ps = j->data; sess_conn = 0; if (flags->replace_sess_conn) sess_conn = 1; else { for (k = session->media_streams.head; k; k = k->next) { sdp_media = k->data; if (!sdp_media->connection.parsed) { sess_conn = 1; break; } } } if (session->origin.parsed && flags->replace_origin && !flags->ice_force_relay) { if (replace_network_address(chop, &session->origin.address, ps, flags)) goto error; } if (session->connection.parsed && sess_conn && !flags->ice_force_relay) { if (replace_network_address(chop, &session->connection.address, ps, flags)) goto error; } if (!MEDIA_ISSET(call_media, PASSTHRU)) { if (process_session_attributes(chop, &session->attributes, flags)) goto error; } media_index = 1; for (k = session->media_streams.head; k; k = k->next) { sdp_media = k->data; if (!m) goto error; call_media = m->data; if (call_media->index != media_index) goto error; j = call_media->streams.head; if (!j) goto error; ps = j->data; if (!flags->ice_force_relay) { if (replace_media_port(chop, sdp_media, ps)) goto error; if (replace_consecutive_port_count(chop, sdp_media, ps, j)) goto error; if (replace_transport_protocol(chop, sdp_media, call_media)) goto error; if (sdp_media->connection.parsed) { if (replace_network_address(chop, &sdp_media->connection.address, ps, flags)) goto error; } } if (process_media_attributes(chop, sdp_media, flags, call_media)) goto error; copy_up_to_end_of(chop, &sdp_media->s); ps_rtcp = NULL; if (ps->rtcp_sibling) { ps_rtcp = ps->rtcp_sibling; j = j->next; if (!j) goto error; assert(j->data == ps_rtcp); } if (!sdp_media->port_num || !ps->sfd) goto next; if (MEDIA_ARESET2(call_media, SEND, RECV)) chopper_append_c(chop, "a=sendrecv\r\n"); else if (MEDIA_ISSET(call_media, SEND)) chopper_append_c(chop, "a=sendonly\r\n"); else if (MEDIA_ISSET(call_media, RECV)) chopper_append_c(chop, "a=recvonly\r\n"); else chopper_append_c(chop, "a=inactive\r\n"); if (call_media->protocol && call_media->protocol->rtp) { if (MEDIA_ISSET(call_media, RTCP_MUX) && flags->opmode == OP_ANSWER) { chopper_append_c(chop, "a=rtcp:"); chopper_append_printf(chop, "%hu", ps->sfd->fd.localport); chopper_append_c(chop, "\r\na=rtcp-mux\r\n"); ps_rtcp = NULL; } else if (ps_rtcp && !flags->ice_force_relay) { chopper_append_c(chop, "a=rtcp:"); chopper_append_printf(chop, "%hu", ps_rtcp->sfd->fd.localport); if (!MEDIA_ISSET(call_media, RTCP_MUX)) chopper_append_c(chop, "\r\n"); else chopper_append_c(chop, "\r\na=rtcp-mux\r\n"); } } else ps_rtcp = NULL; insert_crypto(call_media, chop); insert_dtls(call_media, chop); if (MEDIA_ISSET(call_media, ICE) && call_media->ice_agent) { chopper_append_c(chop, "a=ice-ufrag:"); chopper_append_str(chop, &call_media->ice_agent->ufrag[1]); chopper_append_c(chop, "\r\na=ice-pwd:"); chopper_append_str(chop, &call_media->ice_agent->pwd[1]); chopper_append_c(chop, "\r\n"); } if (!flags->ice_remove) insert_candidates(chop, ps, ps_rtcp, flags, sdp_media); next: media_index++; m = m->next; } } copy_remainder(chop); return 0; error: ilog(LOG_ERROR, "Error rewriting SDP"); return -1; }