ports/net/ser/files/patch-modules::nathelper::nathelper.c

649 lines
19 KiB
C

$FreeBSD$
--- modules/nathelper/nathelper.c.orig Mon Jun 23 22:34:37 2003
+++ modules/nathelper/nathelper.c Sat Aug 2 09:03:54 2003
@@ -5,6 +5,10 @@
* we received this message from
* fix_nated_sdp() - replaces IP address in the SDP with IP address
* and/or adds direction=active option to the SDP
+ * force_rtp_proxy() - rewrite IP address and UDP port in the SDP
+ * body in such a way that RTP traffic visits
+ * RTP proxy running on the same machine as a
+ * ser itself
*
* Beware, those functions will only work correctly if the UA supports
* symmetric signalling and media (not all do)!!!
@@ -48,9 +52,15 @@
#include "../../timer.h"
#include "../../ut.h"
#include "../registrar/sip_msg.h"
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <ctype.h>
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
MODULE_VERSION
@@ -58,6 +68,14 @@
static int fix_nated_sdp_f(struct sip_msg *, char *, char *);
static int update_clen(struct sip_msg *, int);
static int extract_mediaip(str *, str *);
+static int extract_mediaport(str *, str *);
+static int alter_mediaip(struct sip_msg *, str *, str *, str *, int *, int);
+static int alter_mediaport(struct sip_msg *, str *, str *, str *, int *, int);
+static int fixate_sdp_f(struct sip_msg *, char *, char *);
+static char *send_rtpp_command(str *, char, int);
+static int unforce_rtp_proxy_f(struct sip_msg *, char *, char *);
+static int force_rtp_proxy_f(struct sip_msg *, char *, char *);
+
static void timer(unsigned int, void *);
inline static int fixup_str2int(void**, int);
static int mod_init(void);
@@ -71,12 +89,15 @@
static cmd_export_t cmds[]={
{"fix_nated_contact", fix_nated_contact_f, 0, 0, REQUEST_ROUTE | ONREPLY_ROUTE },
{"fix_nated_sdp", fix_nated_sdp_f, 1, fixup_str2int, REQUEST_ROUTE | ONREPLY_ROUTE },
- {0,0,0,0,0}
+ {"fixate_sdp", fixate_sdp_f, 0, 0, REQUEST_ROUTE | ONREPLY_ROUTE },
+ {"force_rtp_proxy", force_rtp_proxy_f, 0, 0, REQUEST_ROUTE | ONREPLY_ROUTE },
+ {"unforce_rtp_proxy", unforce_rtp_proxy_f, 0, 0, REQUEST_ROUTE | ONREPLY_ROUTE },
+ {0, 0, 0, 0, 0}
};
static param_export_t params[]={
{"natping_interval", INT_PARAM, &natping_interval},
- {0,0,0}
+ {0, 0, 0}
};
struct module_exports exports={
@@ -268,21 +289,28 @@
#define ADD_ADIRECTION 0x01
#define FIX_MEDIAIP 0x02
+#define ADD_ANORTPPROXY 0x04
#define ADIRECTION "a=direction:active\r\n"
-#define ADIRECTION_LEN 21
+#define ADIRECTION_LEN 20
#define AOLDMEDIAIP "a=oldmediaip:"
#define AOLDMEDIAIP_LEN 13
+#define AOLDMEDIPRT "a=oldmediaport:"
+#define AOLDMEDIPRT_LEN 15
+
+#define ANORTPPROXY "a=nortpproxy:yes\r\n"
+#define ANORTPPROXY_LEN 18
+
#define CLEN_LEN 10
static int
fix_nated_sdp_f(struct sip_msg* msg, char* str1, char* str2)
{
- str body, mediaip;
- int level, added_len, offset, len;
- char *buf, *cp;
+ str body, body1, oldip, oldip1, newip;
+ int level, added_len;
+ char *buf;
struct lump* anchor;
level = (int)(long)str1;
@@ -293,82 +321,66 @@
return -1;
}
- if (level & ADD_ADIRECTION) {
+ if (level & (ADD_ADIRECTION | ADD_ANORTPPROXY)) {
anchor = anchor_lump(&(msg->add_rm),
body.s + body.len - msg->buf, 0, 0);
if (anchor == NULL) {
LOG(L_ERR, "ERROR: fix_nated_sdp: anchor_lump failed\n");
return -1;
}
- buf = pkg_malloc(ADIRECTION_LEN * sizeof(char));
- if (buf == NULL) {
- LOG(L_ERR, "ERROR: fix_nated_sdp: out of memory\n");
- return -1;
+ if (level & ADD_ADIRECTION) {
+ buf = pkg_malloc(ADIRECTION_LEN * sizeof(char));
+ if (buf == NULL) {
+ LOG(L_ERR, "ERROR: fix_nated_sdp: out of memory\n");
+ return -1;
+ }
+ memcpy(buf, ADIRECTION, ADIRECTION_LEN);
+ if (insert_new_lump_after(anchor, buf, ADIRECTION_LEN, 0) == NULL) {
+ LOG(L_ERR, "ERROR: fix_nated_sdp: insert_new_lump_after failed\n");
+ pkg_free(buf);
+ return -1;
+ }
+ added_len += ADIRECTION_LEN;
}
- memcpy(buf, ADIRECTION, ADIRECTION_LEN);
- if (insert_new_lump_after(anchor, buf, ADIRECTION_LEN - 1, 0) == NULL) {
- LOG(L_ERR, "ERROR: fix_nated_sdp: insert_new_lump_after failed\n");
- pkg_free(buf);
- return -1;
+ if (level & ADD_ANORTPPROXY) {
+ buf = pkg_malloc(ANORTPPROXY_LEN * sizeof(char));
+ if (buf == NULL) {
+ LOG(L_ERR, "ERROR: fix_nated_sdp: out of memory\n");
+ return -1;
+ }
+ memcpy(buf, ANORTPPROXY, ANORTPPROXY_LEN);
+ if (insert_new_lump_after(anchor, buf, ANORTPPROXY_LEN, 0) == NULL) {
+ LOG(L_ERR, "ERROR: fix_nated_sdp: insert_new_lump_after failed\n");
+ pkg_free(buf);
+ return -1;
+ }
+ added_len += ANORTPPROXY_LEN;
}
- added_len += ADIRECTION_LEN - 1;
}
if (level & FIX_MEDIAIP) {
- if (extract_mediaip(&body, &mediaip) == -1) {
+ if (extract_mediaip(&body, &oldip) == -1) {
LOG(L_ERR, "ERROR: fix_nated_sdp: can't extract media IP from the SDP\n");
goto finalise;
}
-
- /* check that updating mediaip is really necessary */
- if (7 == mediaip.len && memcmp("0.0.0.0", mediaip.s, 7) == 0)
- goto finalise;
- cp = ip_addr2a(&msg->rcv.src_ip);
- len = strlen(cp);
- if (len == mediaip.len && memcmp(cp, mediaip.s, len) == 0)
- goto finalise;
-
- anchor = anchor_lump(&(msg->add_rm),
- body.s + body.len - msg->buf, 0, 0);
- if (anchor == NULL) {
- LOG(L_ERR, "ERROR: fix_nated_sdp: anchor_lump failed\n");
- return -1;
- }
- buf = pkg_malloc(AOLDMEDIAIP_LEN + mediaip.len + CRLF_LEN);
- if (buf == NULL) {
- LOG(L_ERR, "ERROR: fix_nated_sdp: out of memory\n");
- return -1;
- }
- memcpy(buf, AOLDMEDIAIP, AOLDMEDIAIP_LEN);
- memcpy(buf + AOLDMEDIAIP_LEN, mediaip.s, mediaip.len);
- memcpy(buf + AOLDMEDIAIP_LEN + mediaip.len, CRLF, CRLF_LEN);
- if (insert_new_lump_after(anchor, buf,
- AOLDMEDIAIP_LEN + mediaip.len + CRLF_LEN, 0) == NULL) {
- LOG(L_ERR, "ERROR: fix_nated_sdp: insert_new_lump_after failed\n");
- pkg_free(buf);
- return -1;
+ body1.s = oldip.s + oldip.len;
+ body1.len = body.s + body.len - body1.s;
+ if (extract_mediaip(&body1, &oldip1) == -1) {
+ oldip1.len = 0;
}
- added_len += AOLDMEDIAIP_LEN + mediaip.len + CRLF_LEN;
- buf = pkg_malloc(len);
- if (buf == NULL) {
- LOG(L_ERR, "ERROR: fix_nated_sdp: out of memory\n");
- return -1;
- }
- offset = mediaip.s - msg->buf;
- anchor = del_lump(&msg->add_rm, offset, mediaip.len, 0);
- if (anchor == NULL) {
- LOG(L_ERR, "ERROR: fix_nated_sdp: del_lump failed\n");
- pkg_free(buf);
+ newip.s = ip_addr2a(&msg->rcv.src_ip);
+ newip.len = strlen(newip.s);
+ if (alter_mediaip(msg, &body, &oldip, &newip,
+ &added_len, 1) == -1) {
+ LOG(L_ERR, "ERROR: fix_nated_sdp: can't alter media IP");
return -1;
}
- memcpy(buf, cp, len);
- if (insert_new_lump_after(anchor, buf, len, 0) == 0) {
- LOG(L_ERR, "ERROR: fix_nated_sdp: insert_new_lump_after failed\n");
- pkg_free(buf);
+ if (oldip1.len > 0 && alter_mediaip(msg, &body, &oldip1, &newip,
+ &added_len, 0) == -1) {
+ LOG(L_ERR, "ERROR: fix_nated_sdp: can't alter media IP");
return -1;
}
- added_len += len - mediaip.len;
}
finalise:
@@ -425,7 +437,7 @@
cp = cp1 + 2;
}
if (cp1 == NULL) {
- LOG(L_ERR, "ERROR: extract_mediaip: no `c=' in SDP\n");
+ LOG(L_DBG, "ERROR: extract_mediaip: no `c=' in SDP\n");
return -1;
}
mediaip->s = cp1 + 2;
@@ -449,6 +461,418 @@
LOG(L_ERR, "ERROR: extract_mediaip: no `IP4' in `c=' field\n");
return -1;
}
+ return 1;
+}
+
+static int
+extract_mediaport(str *body, str *mediaport)
+{
+ char *cp, *cp1;
+ int len;
+
+ cp1 = NULL;
+ for (cp = body->s; (len = body->s + body->len - cp) > 0;) {
+ cp1 = ser_memmem(cp, "m=", len, 2);
+ if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r')
+ break;
+ cp = cp1 + 2;
+ }
+ if (cp1 == NULL) {
+ LOG(L_ERR, "ERROR: extract_mediaport: no `m=' in SDP\n");
+ return -1;
+ }
+ mediaport->s = cp1 + 2;
+ mediaport->len = eat_line(mediaport->s, body->s + body->len -
+ mediaport->s) - mediaport->s;
+ trim_len(mediaport->len, mediaport->s, *mediaport);
+
+ if (mediaport->len < 7 || memcmp(mediaport->s, "audio", 5) != 0 ||
+ !isspace(mediaport->s[5])) {
+ LOG(L_ERR, "ERROR: extract_mediaport: can't parse `m=' in SDP\n");
+ return -1;
+ }
+ cp = eat_space_end(mediaport->s + 5, mediaport->s + mediaport->len);
+ mediaport->len = eat_token_end(cp, mediaport->s + mediaport->len) - cp;
+ mediaport->s = cp;
+ return 1;
+}
+
+static int
+alter_mediaip(struct sip_msg *msg, str *body, str *oldip, str *newip,
+ int *clendelta, int preserve)
+{
+ char *buf;
+ int offset;
+ struct lump* anchor;
+
+ /* check that updating mediaip is really necessary */
+ if (7 == oldip->len && memcmp("0.0.0.0", oldip->s, 7) == 0)
+ return 0;
+ if (newip->len == oldip->len &&
+ memcmp(newip->s, oldip->s, newip->len) == 0)
+ return 0;
+
+ if (preserve != 0) {
+ anchor = anchor_lump(&(msg->add_rm),
+ body->s + body->len - msg->buf, 0, 0);
+ if (anchor == NULL) {
+ LOG(L_ERR, "ERROR: alter_mediaip: anchor_lump failed\n");
+ return -1;
+ }
+ buf = pkg_malloc(AOLDMEDIAIP_LEN + oldip->len + CRLF_LEN);
+ if (buf == NULL) {
+ LOG(L_ERR, "ERROR: alter_mediaip: out of memory\n");
+ return -1;
+ }
+ memcpy(buf, AOLDMEDIAIP, AOLDMEDIAIP_LEN);
+ memcpy(buf + AOLDMEDIAIP_LEN, oldip->s, oldip->len);
+ memcpy(buf + AOLDMEDIAIP_LEN + oldip->len, CRLF, CRLF_LEN);
+ if (insert_new_lump_after(anchor, buf,
+ AOLDMEDIAIP_LEN + oldip->len + CRLF_LEN, 0) == NULL) {
+ LOG(L_ERR, "ERROR: alter_mediaip: insert_new_lump_after failed\n");
+ pkg_free(buf);
+ return -1;
+ }
+ *clendelta += AOLDMEDIAIP_LEN + oldip->len + CRLF_LEN;
+ }
+
+ buf = pkg_malloc(newip->len);
+ if (buf == NULL) {
+ LOG(L_ERR, "ERROR: alter_mediaip: out of memory\n");
+ return -1;
+ }
+ offset = oldip->s - msg->buf;
+ anchor = del_lump(&msg->add_rm, offset, oldip->len, 0);
+ if (anchor == NULL) {
+ LOG(L_ERR, "ERROR: alter_mediaip: del_lump failed\n");
+ pkg_free(buf);
+ return -1;
+ }
+ memcpy(buf, newip->s, newip->len);
+ if (insert_new_lump_after(anchor, buf, newip->len, 0) == 0) {
+ LOG(L_ERR, "ERROR: alter_mediaip: insert_new_lump_after failed\n");
+ pkg_free(buf);
+ return -1;
+ }
+ *clendelta += newip->len - oldip->len;
+ return 0;
+}
+
+static int
+alter_mediaport(struct sip_msg *msg, str *body, str *oldport, str *newport,
+ int *clendelta, int preserve)
+{
+ char *buf;
+ int offset;
+ struct lump* anchor;
+
+ /* check that updating mediaport is really necessary */
+ if (newport->len == oldport->len &&
+ memcmp(newport->s, oldport->s, newport->len) == 0)
+ return 0;
+
+ if (preserve != 0) {
+ anchor = anchor_lump(&(msg->add_rm),
+ body->s + body->len - msg->buf, 0, 0);
+ if (anchor == NULL) {
+ LOG(L_ERR, "ERROR: alter_mediaport: anchor_lump failed\n");
+ return -1;
+ }
+ buf = pkg_malloc(AOLDMEDIPRT_LEN + oldport->len + CRLF_LEN);
+ if (buf == NULL) {
+ LOG(L_ERR, "ERROR: alter_mediaport: out of memory\n");
+ return -1;
+ }
+ memcpy(buf, AOLDMEDIPRT, AOLDMEDIPRT_LEN);
+ memcpy(buf + AOLDMEDIPRT_LEN, oldport->s, oldport->len);
+ memcpy(buf + AOLDMEDIPRT_LEN + oldport->len, CRLF, CRLF_LEN);
+ if (insert_new_lump_after(anchor, buf,
+ AOLDMEDIPRT_LEN + oldport->len + CRLF_LEN, 0) == NULL) {
+ LOG(L_ERR, "ERROR: alter_mediaport: insert_new_lump_after failed\n");
+ pkg_free(buf);
+ return -1;
+ }
+ *clendelta += AOLDMEDIPRT_LEN + oldport->len + CRLF_LEN;
+ }
+
+ buf = pkg_malloc(newport->len);
+ if (buf == NULL) {
+ LOG(L_ERR, "ERROR: alter_mediaport: out of memory\n");
+ return -1;
+ }
+ offset = oldport->s - msg->buf;
+ anchor = del_lump(&msg->add_rm, offset, oldport->len, 0);
+ if (anchor == NULL) {
+ LOG(L_ERR, "ERROR: alter_mediaport: del_lump failed\n");
+ pkg_free(buf);
+ return -1;
+ }
+ memcpy(buf, newport->s, newport->len);
+ if (insert_new_lump_after(anchor, buf, newport->len, 0) == 0) {
+ LOG(L_ERR, "ERROR: alter_mediaport: insert_new_lump_after failed\n");
+ pkg_free(buf);
+ return -1;
+ }
+ *clendelta += newport->len - oldport->len;
+ return 0;
+}
+
+static int
+fixate_sdp_f(struct sip_msg* msg, char* str1, char* str2)
+{
+ char *cp, *cp1;
+ int len, cldelta;
+ str body, body1, newip, newip1, newport, dest, oldip, oldport;
+ struct sip_uri ruri;
+ struct hdr_field *hdr;
+ struct via_body *rvia;
+
+ if (msg->first_line.type == SIP_REQUEST &&
+ msg->first_line.u.request.method_value == METHOD_INVITE) {
+ LOG(L_ERR, "DEBUG: fixate_sdp: request\n");
+ if (msg->parsed_uri_ok) {
+ dest = msg->parsed_uri.host;
+ } else {
+ if (parse_uri(msg->new_uri.s, msg->new_uri.len, &ruri) < 0) {
+ LOG(L_ERR, "ERROR: fixate_sdp: can't parse request uri\n");
+ return -1;
+ }
+ dest = ruri.host;
+ }
+ } else if (msg->first_line.type == SIP_REPLY) {
+ LOG(L_ERR, "DEBUG: fixate_sdp: reply\n");
+ rvia = NULL;
+ for (hdr=msg->headers; hdr; hdr=hdr->next) {
+ if (hdr->type == HDR_VIA)
+ rvia = hdr->parsed;
+ }
+ if (rvia == NULL) {
+ LOG(L_ERR, "ERROR: fixate_sdp: no or incorrect Via in reply\n");
+ return -1;
+ }
+ if (rvia->received != NULL) {
+ dest = rvia->received->value;
+ } else {
+ dest = rvia->host;
+ }
+ } else {
+ return -1;
+ }
+
+ if (extract_body(msg, &body) == -1 || body.len == 0)
+ return -1;
+ if (extract_mediaip(&body, &newip) == -1) {
+ LOG(L_ERR, "ERROR: fixate_sdp: can't extract media IP from the SDP\n");
+ return -1;
+ }
+ body1.s = newip.s + newip.len;
+ body1.len = body.s + body.len - body1.s;
+ if (extract_mediaip(&body1, &newip1) == -1) {
+ newip1.len = 0;
+ }
+ if (newip.len != dest.len || memcmp(newip.s, dest.s, dest.len) != 0)
+ return -1;
+ if (extract_mediaport(&body, &newport) == -1) {
+ LOG(L_ERR, "ERROR: fixate_sdp: can't extract media port from the SDP\n");
+ return -1;
+ }
+
+ for (cp = body.s; (len = body.s + body.len - cp) >= AOLDMEDIAIP_LEN;) {
+ cp1 = ser_memmem(cp, AOLDMEDIAIP, len, AOLDMEDIAIP_LEN);
+ if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r')
+ break;
+ cp = cp1 + AOLDMEDIAIP_LEN;
+ }
+ if (cp1 == NULL) {
+ oldip.len = 0;
+ } else {
+ oldip.s = cp1 + AOLDMEDIAIP_LEN;
+ oldip.len = eat_line(oldip.s, body.s + body.len -
+ oldip.s) - oldip.s;
+ trim_len(oldip.len, oldip.s, oldip);
+ }
+ if (newip.len == oldip.len &&
+ memcmp(newip.s, oldip.s, newip.len) == 0)
+ oldip.len = 0;
+
+ for (cp = body.s; (len = body.s + body.len - cp) >= AOLDMEDIPRT_LEN;) {
+ cp1 = ser_memmem(cp, AOLDMEDIPRT, len, AOLDMEDIPRT_LEN);
+ if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r')
+ break;
+ cp = cp1 + AOLDMEDIPRT_LEN;
+ }
+ if (cp1 == NULL) {
+ oldport.len = 0;
+ } else {
+ oldport.s = cp1 + AOLDMEDIPRT_LEN;
+ oldport.len = eat_line(oldport.s, body.s + body.len -
+ oldport.s) - oldport.s;
+ trim_len(oldport.len, oldport.s, oldport);
+ }
+ if (newport.len == oldport.len &&
+ memcmp(newport.s, oldport.s, newport.len) == 0)
+ oldport.len = 0;
+
+ cldelta = 0;
+
+ if (oldip.len != 0) {
+ if (alter_mediaip(msg, &body, &newip, &oldip,
+ &cldelta, 0) == -1)
+ return -1;
+ if (newip1.len > 0 && alter_mediaip(msg, &body1, &newip1,
+ &oldip, &cldelta, 0) == -1)
+ return -1;
+ }
+ if (oldport.len != 0 &&
+ alter_mediaport(msg, &body, &newport, &oldport, &cldelta, 0) == -1)
+ return -1;
+
+ if (cldelta == 0)
+ return 1;
+
+ return (update_clen(msg, body.len + cldelta));
+}
+
+static char *
+send_rtpp_command(str *callid, char command, int getreply)
+{
+ struct sockaddr_un addr;
+ int fd, len;
+ struct iovec v[3];
+ static char buf[16];
+ char cmd[2] = {' ', ' '};
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_LOCAL;
+ strncpy(addr.sun_path, "/var/run/rtpproxy.sock",
+ sizeof(addr.sun_path) - 1);
+#if !defined(__linux__)
+ addr.sun_len = strlen(addr.sun_path);
+#endif
+
+ fd = socket(AF_LOCAL, SOCK_STREAM, 0);
+ if (fd < 0) {
+ LOG(L_ERR, "ERROR: send_rtpp_command: can't create socket\n");
+ return NULL;
+ }
+ if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ close(fd);
+ LOG(L_ERR, "ERROR: send_rtpp_command: can't connect to RTP proxy\n");
+ return NULL;
+ }
+
+ cmd[0] = command;
+ v[0].iov_base = cmd;
+ v[0].iov_len = 2;
+ v[1].iov_base = callid->s;
+ v[1].iov_len = callid->len;
+ v[2].iov_base = "\n";
+ v[2].iov_len = 1;
+ do {
+ len = writev(fd, v, 3);
+ } while (len == -1 && errno == EINTR);
+ if (len <= 0) {
+ close(fd);
+ LOG(L_ERR, "ERROR: send_rtpp_command: can't send command to a RTP proxy\n");
+ return NULL;
+ }
+
+ if (getreply != 0) {
+ do {
+ len = read(fd, buf, sizeof(buf) - 1);
+ } while (len == -1 && errno == EINTR);
+ close(fd);
+ if (len <= 0) {
+ LOG(L_ERR, "ERROR: send_rtpp_command: can't read reply from a RTP proxy\n");
+ return NULL;
+ }
+ buf[len] = '\0';
+ }
+
+ return buf;
+}
+
+static int
+unforce_rtp_proxy_f(struct sip_msg* msg, char* str1, char* str2)
+{
+
+ if (msg->callid == NULL || msg->callid->body.len <= 0) {
+ LOG(L_ERR, "ERROR: unforce_rtp_proxy: no Call-Id field\n");
+ return -1;
+ }
+ send_rtpp_command(&(msg->callid->body), 'D', 0);
+
+ return 1;
+}
+
+static int
+force_rtp_proxy_f(struct sip_msg* msg, char* str1, char* str2)
+{
+ str body, body1, oldport, oldip, oldip1, newport, newip;
+ int create, port, cldelta, len;
+ char buf[16];
+ char *cp, *cp1;
+
+ if (msg->first_line.type == SIP_REQUEST &&
+ msg->first_line.u.request.method_value == METHOD_INVITE) {
+ create = 1;
+ } else if (msg->first_line.type == SIP_REPLY) {
+ create = 0;
+ } else {
+ return -1;
+ }
+ if (msg->callid == NULL || msg->callid->body.len <= 0) {
+ LOG(L_ERR, "ERROR: force_rtp_proxy: no Call-Id field\n");
+ return -1;
+ }
+ if (extract_body(msg, &body) == -1 || body.len == 0)
+ return -1;
+ for (cp = body.s; (len = body.s + body.len - cp) >= ANORTPPROXY_LEN;) {
+ cp1 = ser_memmem(cp, ANORTPPROXY, len, ANORTPPROXY_LEN);
+ if (cp1 == NULL)
+ break;
+ if (cp1[-1] == '\n' || cp1[-1] == '\r')
+ return 1;
+ cp = cp1 + ANORTPPROXY_LEN;
+ }
+ if (extract_mediaip(&body, &oldip) == -1) {
+ LOG(L_ERR, "ERROR: force_rtp_proxy: can't extract media IP from the message\n");
+ return -1;
+ }
+ body1.s = oldip.s + oldip.len;
+ body1.len = body.s + body.len - body1.s;
+ if (extract_mediaip(&body1, &oldip1) == -1) {
+ oldip1.len = 0;
+ }
+ if (extract_mediaport(&body, &oldport) == -1) {
+ LOG(L_ERR, "ERROR: force_rtp_proxy: can't extract media port from the message\n");
+ return -1;
+ }
+ cp = send_rtpp_command(&(msg->callid->body), create ? 'U' : 'L', 1);
+ if (cp == NULL)
+ return -1;
+ port = atoi(cp);
+ if (port <= 0 || port > 65535)
+ return -1;
+
+ newport.s = buf;
+ newport.len = sprintf(buf, "%d", port);
+ newip.s = ip_addr2a(&msg->rcv.dst_ip);
+ newip.len = strlen(newip.s);
+
+ cldelta = 0;
+ if (alter_mediaip(msg, &body, &oldip, &newip, &cldelta, 0) == -1)
+ return -1;
+ if (oldip1.len > 0 &&
+ alter_mediaip(msg, &body1, &oldip1, &newip, &cldelta, 0) == -1)
+ return -1;
+ if (alter_mediaport(msg, &body, &oldport, &newport, &cldelta, 0) == -1)
+ return -1;
+
+ if (cldelta == 0)
+ return 1;
+
+ return (update_clen(msg, body.len + cldelta));
return 1;
}