📄 nathelper.c
字号:
static inline int replace_sdp_ip(struct sip_msg* msg, str *org_body, char *line, str *ip){ str body1, oldip, newip; str body = *org_body; unsigned hasreplaced = 0; int pf, pf1 = 0; str body2; char *bodylimit = body.s + body.len; /* Iterate all lines and replace ips in them. */ if (!ip) { newip.s = ip_addr2a(&msg->rcv.src_ip); newip.len = strlen(newip.s); } else { newip = *ip; } body1 = body; for(;;) { if (extract_mediaip(&body1, &oldip, &pf,line) == -1) break; if (pf != AF_INET) { LOG(L_ERR, "ERROR: fix_nated_sdp: " "not an IPv4 address in '%s' SDP\n",line); return -1; } if (!pf1) pf1 = pf; else if (pf != pf1) { LOG(L_ERR, "ERROR: fix_nated_sdp: mismatching " "address families in '%s' SDP\n",line); return -1; } body2.s = oldip.s + oldip.len; body2.len = bodylimit - body2.s; if (alter_mediaip(msg, &body1, &oldip, pf, &newip, pf,1) == -1) { LOG(L_ERR, "ERROR: fix_nated_sdp: can't alter '%s' IP\n",line); return -1; } hasreplaced = 1; body1 = body2; } if (!hasreplaced) { LOG(L_ERR, "ERROR: fix_nated_sdp: can't extract '%s' IP " "from the SDP\n",line); return -1; } return 0;}static intfix_nated_sdp_f(struct sip_msg* msg, char* str1, char* str2){ str body; str ip; int level; char *buf; struct lump* anchor; level = (int)(long)str1; if (str2 && xl_printf_s( msg, (xl_elem_p)str2, &ip)!=0) return -1; if (extract_body(msg, &body) == -1) { LOG(L_ERR,"ERROR: fix_nated_sdp: cannot extract body from msg!\n"); return -1; } if (level & (ADD_ADIRECTION | ADD_ANORTPPROXY)) { msg->msg_flags |= FL_FORCE_ACTIVE; anchor = anchor_lump(msg, body.s + body.len - msg->buf, 0, 0); if (anchor == NULL) { LOG(L_ERR, "ERROR: fix_nated_sdp: anchor_lump failed\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; } } 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; } } } if (level & FIX_MEDIP) { /* Iterate all c= and replace ips in them. */ if (replace_sdp_ip(msg, &body, "c=", str2?&ip:0)==-1) return -1; } if (level & FIX_ORGIP) { /* Iterate all o= and replace ips in them. */ if (replace_sdp_ip(msg, &body, "o=", str2?&ip:0)==-1) return -1; } return 1;}static intextract_mediaip(str *body, str *mediaip, int *pf, char *line){ char *cp, *cp1; int len, nextisip; cp1 = NULL; for (cp = body->s; (len = body->s + body->len - cp) > 0;) { cp1 = ser_memmem(cp, line, len, 2); if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r') break; cp = cp1 + 2; } if (cp1 == NULL) return -1; mediaip->s = cp1 + 2; mediaip->len = eat_line(mediaip->s, body->s + body->len - mediaip->s) - mediaip->s; trim_len(mediaip->len, mediaip->s, *mediaip); nextisip = 0; for (cp = mediaip->s; cp < mediaip->s + mediaip->len;) { len = eat_token_end(cp, mediaip->s + mediaip->len) - cp; if (nextisip == 1) { mediaip->s = cp; mediaip->len = len; nextisip++; break; } if (len == 3 && memcmp(cp, "IP", 2) == 0) { switch (cp[2]) { case '4': nextisip = 1; *pf = AF_INET; break; case '6': nextisip = 1; *pf = AF_INET6; break; default: break; } } cp = eat_space_end(cp + len, mediaip->s + mediaip->len); } if (nextisip != 2 || mediaip->len == 0) { LOG(L_ERR, "ERROR: extract_mediaip: " "no `IP[4|6]' in `%s' field\n",line); return -1; } return 1;}static intextract_mediaport(str *body, str *mediaport){ char *cp, *cp1; int len, i; str ptype; 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; /* skip `m=' */ mediaport->len = eat_line(mediaport->s, body->s + body->len - mediaport->s) - mediaport->s; trim_len(mediaport->len, mediaport->s, *mediaport); /* Skip media supertype and spaces after it */ cp = eat_token_end(mediaport->s, mediaport->s + mediaport->len); mediaport->len -= cp - mediaport->s; if (mediaport->len <= 0 || cp == mediaport->s) { LOG(L_ERR, "ERROR: extract_mediaport: no port in `m='\n"); return -1; } mediaport->s = cp; cp = eat_space_end(mediaport->s, mediaport->s + mediaport->len); mediaport->len -= cp - mediaport->s; if (mediaport->len <= 0 || cp == mediaport->s) { LOG(L_ERR, "ERROR: extract_mediaport: no port in `m='\n"); return -1; } /* Extract port */ mediaport->s = cp; cp = eat_token_end(mediaport->s, mediaport->s + mediaport->len); ptype.len = mediaport->len - (cp - mediaport->s); if (ptype.len <= 0 || cp == mediaport->s) { LOG(L_ERR, "ERROR: extract_mediaport: no port in `m='\n"); return -1; } ptype.s = cp; mediaport->len = cp - mediaport->s; /* Skip spaces after port */ cp = eat_space_end(ptype.s, ptype.s + ptype.len); ptype.len -= cp - ptype.s; if (ptype.len <= 0 || cp == ptype.s) { LOG(L_ERR, "ERROR: extract_mediaport: no protocol type in `m='\n"); return -1; } /* Extract protocol type */ ptype.s = cp; cp = eat_token_end(ptype.s, ptype.s + ptype.len); if (cp == ptype.s) { LOG(L_ERR, "ERROR: extract_mediaport: no protocol type in `m='\n"); return -1; } ptype.len = cp - ptype.s; for (i = 0; sup_ptypes[i].s != NULL; i++) if (ptype.len == sup_ptypes[i].len && strncasecmp(ptype.s, sup_ptypes[i].s, ptype.len) == 0) return 0; /* Unproxyable protocol type. Generally it isn't error. */ return -1;}static intalter_mediaip(struct sip_msg *msg, str *body, str *oldip, int oldpf, str *newip, int newpf, int preserve){ char *buf; int offset; struct lump* anchor; str omip, nip, oip; /* check that updating mediaip is really necessary */ if (oldpf == newpf && isnulladdr(oldip, oldpf)) return 0; if (newip->len == oldip->len && memcmp(newip->s, oldip->s, newip->len) == 0) return 0; if (preserve != 0) { anchor = anchor_lump(msg, body->s + body->len - msg->buf, 0, 0); if (anchor == NULL) { LOG(L_ERR, "ERROR: alter_mediaip: anchor_lump failed\n"); return -1; } if (oldpf == AF_INET6) { omip.s = AOLDMEDIP6; omip.len = AOLDMEDIP6_LEN; } else { omip.s = AOLDMEDIP; omip.len = AOLDMEDIP_LEN; } buf = pkg_malloc(omip.len + oldip->len + CRLF_LEN); if (buf == NULL) { LOG(L_ERR, "ERROR: alter_mediaip: out of memory\n"); return -1; } memcpy(buf, omip.s, omip.len); memcpy(buf + omip.len, oldip->s, oldip->len); memcpy(buf + omip.len + oldip->len, CRLF, CRLF_LEN); if (insert_new_lump_after(anchor, buf, omip.len + oldip->len + CRLF_LEN, 0) == NULL) { LOG(L_ERR, "ERROR: alter_mediaip: insert_new_lump_after failed\n"); pkg_free(buf); return -1; } } if (oldpf == newpf) { nip.len = newip->len; nip.s = pkg_malloc(nip.len); if (nip.s == NULL) { LOG(L_ERR, "ERROR: alter_mediaip: out of memory\n"); return -1; } memcpy(nip.s, newip->s, newip->len); } else { nip.len = newip->len + 2; nip.s = pkg_malloc(nip.len); if (nip.s == NULL) { LOG(L_ERR, "ERROR: alter_mediaip: out of memory\n"); return -1; } memcpy(nip.s + 2, newip->s, newip->len); nip.s[0] = (newpf == AF_INET6) ? '6' : '4'; nip.s[1] = ' '; } oip = *oldip; if (oldpf != newpf) { do { oip.s--; oip.len++; } while (*oip.s != '6' && *oip.s != '4'); } offset = oip.s - msg->buf; anchor = del_lump(msg, offset, oip.len, 0); if (anchor == NULL) { LOG(L_ERR, "ERROR: alter_mediaip: del_lump failed\n"); pkg_free(nip.s); return -1; } if (insert_new_lump_after(anchor, nip.s, nip.len, 0) == 0) { LOG(L_ERR, "ERROR: alter_mediaip: insert_new_lump_after failed\n"); pkg_free(nip.s); return -1; } return 0;}static intalter_mediaport(struct sip_msg *msg, str *body, str *oldport, str *newport, 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; /* * Since rewriting the same info twice will mess SDP up, * apply simple anti foot shooting measure - put flag on * messages that have been altered and check it when * another request comes. */#if 0 /* disabled: - it propagates to the reply and we don't want this * -- andrei */ if (msg->msg_flags & FL_SDP_PORT_AFS) { LOG(L_ERR, "ERROR: alter_mediaip: you can't rewrite the same " "SDP twice, check your config!\n"); return -1; }#endif if (preserve != 0) { anchor = anchor_lump(msg, 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(AOLDMEDPRT_LEN + oldport->len + CRLF_LEN); if (buf == NULL) { LOG(L_ERR, "ERROR: alter_mediaport: out of memory\n"); return -1; } memcpy(buf, AOLDMEDPRT, AOLDMEDPRT_LEN); memcpy(buf + AOLDMEDPRT_LEN, oldport->s, oldport->len); memcpy(buf + AOLDMEDPRT_LEN + oldport->len, CRLF, CRLF_LEN); if (insert_new_lump_after(anchor, buf, AOLDMEDPRT_LEN + oldport->len + CRLF_LEN, 0) == NULL) { LOG(L_ERR, "ERROR: alter_mediaport: insert_new_lump_after failed\n"); pkg_free(buf); return -1; } } 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, 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; }#if 0 msg->msg_flags |= FL_SDP_PORT_AFS;#endif return 0;}static char *gencookie(){ static char cook[34]; sprintf(cook, "%d_%u ", (int)mypid, myseqn); myseqn++; return cook;}static intrtpp_test(struct rtpp_node *node, int isdisabled, int force){ int rtpp_ver; char *cp; struct iovec v[2] = {{NULL, 0}, {"V", 1}}; struct iovec vf[4] = {{NULL, 0}, {"VF", 2}, {" ", 1}, {REQ_CPROTOVER, 8}}; if (force == 0) { if (isdisabled == 0) return 0; if (node->rn_recheck_ticks > get_ticks()) return 1; } do { cp = send_rtpp_command(node, v, 2); if (cp == NULL) { LOG(L_WARN,"WARNING: rtpp_test: can't get version of " "the RTP proxy\n"); break; } rtpp_ver = atoi(cp); if (rtpp_ver != SUP_CPROTOVER) { LOG(L_WARN, "WARNING: rtpp_test: unsupported " "version of RTP proxy <%s> found: %d supported, " "%d present\n", node->rn_url, SUP_CPROTOVER, rtpp_ver); break; } cp = send_rtpp_command(node, vf, 4); if (cp == NULL) { LOG(L_WARN,"WARNING: rtpp_test: RTP proxy went down during " "version query\n"); break; } if (cp[0] == 'E' || atoi(cp) != 1) { LOG(L_WARN, "WARNING: rtpp_test: of RTP proxy <%s>" "doesn't support required protocol version %s\n", node->rn_url, REQ_CPROTOVER); break; } LOG(L_INFO, "rtpp_test: RTP proxy <%s> found, support for " "it %senabled\n", node->rn_url, force == 0 ? "re-" : ""); return 0; } while(0); LOG(L_WARN, "WARNING: rtpp_test: support for RTP proxy <%s>" "has been disabled%s\n", node->rn_url, rtpproxy_disable_tout < 0 ? "" : " temporarily");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -