|
|
|
@ -621,19 +621,16 @@ static int skip_over(struct sdp_chopper *chop, str *where) { |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int replace_media_port(struct sdp_chopper *chop, struct sdp_media *media, GList *m, int off) { |
|
|
|
struct callstream *cs; |
|
|
|
struct streamrelay *sr; |
|
|
|
str *port = &media->port; |
|
|
|
int cons; |
|
|
|
|
|
|
|
if (!m) { |
|
|
|
mylog(LOG_ERROR, "BUG! Ran out of streams"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
static void fill_relays(struct streamrelay **rtp, struct streamrelay **rtcp, GList *m, int off, struct stream_input *sip) { |
|
|
|
*rtp = &((struct callstream *) m->data)->peers[off].rtps[0]; |
|
|
|
if (rtcp) |
|
|
|
*rtcp = &((struct callstream *) m->data)->peers[off].rtps[1]; |
|
|
|
if (sip && sip->has_rtcp && m->next) |
|
|
|
*rtcp = &((struct callstream *) m->next->data)->peers[off].rtps[0]; |
|
|
|
} |
|
|
|
|
|
|
|
cs = m->data; |
|
|
|
sr = &cs->peers[off].rtps[0]; |
|
|
|
static int replace_media_port(struct sdp_chopper *chop, struct sdp_media *media, struct streamrelay *sr) { |
|
|
|
str *port = &media->port; |
|
|
|
|
|
|
|
if (copy_up_to(chop, port)) |
|
|
|
return -1; |
|
|
|
@ -643,6 +640,15 @@ static int replace_media_port(struct sdp_chopper *chop, struct sdp_media *media, |
|
|
|
if (skip_over(chop, port)) |
|
|
|
return -1; |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int replace_consecutive_port_count(struct sdp_chopper *chop, struct sdp_media *media, |
|
|
|
struct streamrelay *rtp, GList *m, int off) |
|
|
|
{ |
|
|
|
int cons; |
|
|
|
struct streamrelay *sr; |
|
|
|
|
|
|
|
if (media->port_count == 1) |
|
|
|
return 0; |
|
|
|
|
|
|
|
@ -650,8 +656,8 @@ static int replace_media_port(struct sdp_chopper *chop, struct sdp_media *media, |
|
|
|
m = m->next; |
|
|
|
if (!m) |
|
|
|
goto warn; |
|
|
|
cs = m->data; |
|
|
|
if (cs->peers[off].rtps[0].fd.localport != sr->fd.localport + cons * 2) { |
|
|
|
fill_relays(&sr, NULL, m, off, NULL); |
|
|
|
if (sr->fd.localport != rtp->fd.localport + cons * 2) { |
|
|
|
warn: |
|
|
|
mylog(LOG_WARN, "Failed to handle consecutive ports"); |
|
|
|
break; |
|
|
|
@ -680,21 +686,11 @@ static int insert_ice_address(struct sdp_chopper *chop, struct sdp_ng_flags *fla |
|
|
|
} |
|
|
|
|
|
|
|
static int replace_network_address(struct sdp_chopper *chop, struct network_address *address, |
|
|
|
GList *m, int off, struct sdp_ng_flags *flags) |
|
|
|
struct streamrelay *sr, struct sdp_ng_flags *flags) |
|
|
|
{ |
|
|
|
struct callstream *cs; |
|
|
|
struct peer *peer; |
|
|
|
char buf[64]; |
|
|
|
int len; |
|
|
|
|
|
|
|
if (!m) { |
|
|
|
mylog(LOG_ERROR, "BUG! Ran out of streams"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
|
|
|
|
cs = m->data; |
|
|
|
peer = &cs->peers[off]; |
|
|
|
|
|
|
|
if (copy_up_to(chop, &address->address_type)) |
|
|
|
return -1; |
|
|
|
|
|
|
|
@ -704,7 +700,7 @@ static int replace_network_address(struct sdp_chopper *chop, struct network_addr |
|
|
|
chopper_append_str(chop, &flags->received_from_address); |
|
|
|
} |
|
|
|
else { |
|
|
|
call_stream_address(buf, peer, SAF_NG, &len); |
|
|
|
call_stream_address(buf, sr->up, SAF_NG, &len); |
|
|
|
chopper_append_dup(chop, buf, len); |
|
|
|
} |
|
|
|
|
|
|
|
@ -798,6 +794,15 @@ strip: |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static GList *find_stream_num(GList *m, int num) { |
|
|
|
/* XXX use a hash instead? must link input streams to output streams */ |
|
|
|
while (m && ((struct callstream *) m->data)->num < num) |
|
|
|
m = m->next; |
|
|
|
while (m && ((struct callstream *) m->data)->num > num) |
|
|
|
m = m->prev; |
|
|
|
return m; |
|
|
|
} |
|
|
|
|
|
|
|
int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call *call, |
|
|
|
enum call_opmode opmode, struct sdp_ng_flags *flags, GHashTable *streamhash) |
|
|
|
{ |
|
|
|
@ -814,12 +819,14 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call *call, |
|
|
|
for (l = sessions->head; l; l = l->next) { |
|
|
|
session = l->data; |
|
|
|
|
|
|
|
fill_relays(&rtp, &rtcp, m, off, NULL); |
|
|
|
|
|
|
|
if (session->origin.parsed && flags->replace_origin) { |
|
|
|
if (replace_network_address(chop, &session->origin.address, m, off, flags)) |
|
|
|
if (replace_network_address(chop, &session->origin.address, rtp, flags)) |
|
|
|
goto error; |
|
|
|
} |
|
|
|
if (session->connection.parsed) { |
|
|
|
if (replace_network_address(chop, &session->connection.address, m, off, flags)) |
|
|
|
if (replace_network_address(chop, &session->connection.address, rtp, flags)) |
|
|
|
goto error; |
|
|
|
} |
|
|
|
|
|
|
|
@ -848,25 +855,18 @@ int sdp_replace(struct sdp_chopper *chop, GQueue *sessions, struct call *call, |
|
|
|
sip = g_hash_table_lookup(streamhash, &si); |
|
|
|
if (!sip) |
|
|
|
goto error; |
|
|
|
/* XXX use a hash instead? must link input streams to output streams */ |
|
|
|
m = find_stream_num(m, sip->stream.num); |
|
|
|
if (!m) |
|
|
|
m = call->callstreams->head; |
|
|
|
while (m && ((struct callstream *) m->data)->num < sip->stream.num) |
|
|
|
m = m->next; |
|
|
|
while (m && ((struct callstream *) m->data)->num > sip->stream.num) |
|
|
|
m = m->prev; |
|
|
|
|
|
|
|
/* XXX use those in function calls exclusively */ |
|
|
|
rtp = &((struct callstream *) m->data)->peers[off].rtps[0]; |
|
|
|
rtcp = &((struct callstream *) m->data)->peers[off].rtps[1]; |
|
|
|
if (sip->has_rtcp && m->next) |
|
|
|
rtcp = &((struct callstream *) m->next->data)->peers[off].rtps[0]; |
|
|
|
|
|
|
|
if (replace_media_port(chop, media, m, off)) |
|
|
|
goto error; |
|
|
|
fill_relays(&rtp, &rtcp, m, off, sip); |
|
|
|
|
|
|
|
if (replace_media_port(chop, media, rtp)) |
|
|
|
goto error; |
|
|
|
if (replace_consecutive_port_count(chop, media, rtp, m, off)) |
|
|
|
goto error; |
|
|
|
|
|
|
|
if (media->connection.parsed && flags->replace_sess_conn) { |
|
|
|
if (replace_network_address(chop, &media->connection.address, m, off, flags)) |
|
|
|
if (replace_network_address(chop, &media->connection.address, rtp, flags)) |
|
|
|
goto error; |
|
|
|
} |
|
|
|
|
|
|
|
|