From bbc53398f8b7daf4fa72b2e06cb064792a985198 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Fri, 12 Jul 2013 11:54:33 -0400 Subject: [PATCH] implement and document ng "media address" --- README.md | 12 ++++++++++-- daemon/call.c | 1 + daemon/sdp.c | 28 +++++++++++++++++++++++----- daemon/sdp.h | 4 +++- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 569d0f0a0..601bfe13b 100644 --- a/README.md +++ b/README.md @@ -520,6 +520,7 @@ Optionally included keys are: If given, the media addresses from the SDP body are trusted as correct endpoints. Otherwise, the address is taken from the `received from` key. Corresponds to the *rtpproxy* `r` flag. + Can be overridden through the `media address` key. - `symmetric` @@ -560,7 +561,7 @@ Optionally included keys are: Contains a list of exactly two elements. The first element denotes the address family and the second element is the SIP message's source address itself. The address family can be one of `IP4` or `IP6`. - Used if the `trust address` flag isn't present. + Used if neither the `trust address` flag nor the `media address` key is present. * `ICE` @@ -582,13 +583,20 @@ Optionally included keys are: Valid values are: `RTP/AVP`, `RTP/AVPF`, `RTP/SAVP`, `RTP/SAVPF`. +* `media address` + + This can be used to override both the addresses present in the SDP body + and the `received from` address. Contains either an IPv4 or an IPv6 address, expressed as a simple + string. The format must be dotted-quad notation for IPv4 or RFC 5952 notation for IPv6. + It's up to the RTP proxy to determine the address family type. + An example of a complete `offer` request dictionary could be (SDP body abbreviated): { "command": "offer", "call-id": "cfBXzDSZqhYNcXM", "from-tag": "mS9rSAn0Cr", "sdp": "v=0\r\no=...", "via-branch": "5KiTRPZHH1nL6", "flags": [ "trust address" ], "replace": [ "origin", "session connection" ], "direction": [ "external", "external" ], "received-from": [ "IP4", "10.65.31.43" ], - "ICE": "force", "transport protocol": "RTP/SAVPF" } + "ICE": "force", "transport protocol": "RTP/SAVPF", "media address": "2001:d8::6f24:65b" } The response message only contains the key `sdp` in addition to `result`, which contains the re-written SDP body that the SIP proxy should insert into the SIP message. diff --git a/daemon/call.c b/daemon/call.c index ccac45816..dd0b519d9 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -2616,6 +2616,7 @@ static void call_ng_process_flags(struct sdp_ng_flags *out, bencode_item_t *inpu if (!out->transport_protocol_str.s) bencode_dictionary_get_str(input, "transport-protocol", &out->transport_protocol_str); out->transport_protocol = transport_protocol(&out->transport_protocol_str); + bencode_dictionary_get_str(input, "media address", &out->media_address); } static unsigned int stream_hash(struct stream_input *s) { diff --git a/daemon/sdp.c b/daemon/sdp.c index b9eddbbc0..12401aea4 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -172,7 +172,7 @@ static inline int inet_pton_str(int af, str *src, void *dst) { int ret; p = s[src->len]; s[src->len] = '\0'; - ret = inet_pton(af, src->s, dst); + ret = smart_pton(af, src->s, dst); s[src->len] = p; return ret; } @@ -187,12 +187,22 @@ static int __parse_address(struct in6_addr *out, str *network_type, str *address && memcmp(network_type->s, "in", 2)) return -1; } + + if (!address_type) { + if (inet_pton_str(AF_INET, address, &in4) == 1) + goto ip4; + if (inet_pton_str(AF_INET6, address, out) == 1) + return 0; + return -1; + } + if (address_type->len != 3) return -1; if (!memcmp(address_type->s, "IP4", 3) || !memcmp(address_type->s, "ip4", 3)) { if (inet_pton_str(AF_INET, address, &in4) != 1) return -1; +ip4: in4_to_6(out, in4.s_addr); } else if (!memcmp(address_type->s, "IP6", 3) @@ -748,13 +758,21 @@ void sdp_free(GQueue *sessions) { static int fill_stream_address(struct stream_input *si, struct sdp_media *media, struct sdp_ng_flags *flags) { struct sdp_session *session = media->session; - if (!flags->trust_address) { - if (is_addr_unspecified(&flags->parsed_address)) { - if (__parse_address(&flags->parsed_address, NULL, &flags->received_from_family, + if (flags->media_address.s) { + if (is_addr_unspecified(&flags->parsed_media_address)) { + if (__parse_address(&flags->parsed_media_address, NULL, NULL, + &flags->media_address)) + return -1; + } + si->stream.ip46 = flags->parsed_media_address; + } + else if (!flags->trust_address) { + if (is_addr_unspecified(&flags->parsed_received_from)) { + if (__parse_address(&flags->parsed_received_from, NULL, &flags->received_from_family, &flags->received_from_address)) return -1; } - si->stream.ip46 = flags->parsed_address; + si->stream.ip46 = flags->parsed_received_from; } else if (media->connection.parsed) si->stream.ip46 = media->connection.address.parsed; diff --git a/daemon/sdp.h b/daemon/sdp.h index e65cfc9c5..cf51eab7b 100644 --- a/daemon/sdp.h +++ b/daemon/sdp.h @@ -10,9 +10,11 @@ struct sdp_ng_flags { int desired_family[2]; str received_from_family; str received_from_address; + str media_address; str transport_protocol_str; enum transport_protocol transport_protocol; - struct in6_addr parsed_address; + struct in6_addr parsed_received_from; + struct in6_addr parsed_media_address; enum stream_direction directions[2]; int asymmetric:1, symmetric:1,