diff options
Diffstat (limited to 'net/ser/files/patch-modules::nathelper::nathelper.c')
-rw-r--r-- | net/ser/files/patch-modules::nathelper::nathelper.c | 649 |
1 files changed, 649 insertions, 0 deletions
diff --git a/net/ser/files/patch-modules::nathelper::nathelper.c b/net/ser/files/patch-modules::nathelper::nathelper.c new file mode 100644 index 000000000000..4acb99ff3e5b --- /dev/null +++ b/net/ser/files/patch-modules::nathelper::nathelper.c @@ -0,0 +1,649 @@ + +$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; + } + |