📄 nathelper.c
字号:
tmpstr1.s = c2p ? c2p : c1p; if (tmpstr1.s == NULL) { /* No "c=" */ LOG(L_ERR, "ERROR: force_rtp_proxy2: can't" " find media IP in the message\n"); return -1; } tmpstr1.len = v2p - tmpstr1.s; /* limit is session limit text */ if (extract_mediaip(&tmpstr1, &oldip, &pf,"c=") == -1) { LOG(L_ERR, "ERROR: force_rtp_proxy2: can't" " extract media IP from the message\n"); return -1; } tmpstr1.s = m1p; tmpstr1.len = m2p - m1p; if (extract_mediaport(&tmpstr1, &oldport) == -1) { LOG(L_ERR, "ERROR: force_rtp_proxy2: can't" " extract media port from the message\n"); return -1; } ++medianum; if (asymmetric != 0 || real != 0) { newip = oldip; } else { newip.s = ip_addr2a(&msg->rcv.src_ip); newip.len = strlen(newip.s); } /* XXX must compare address families in all addresses */ if (pf == AF_INET6) { opts[oidx] = '6'; oidx++; } opts[0] = (create == 0) ? 'L' : 'U'; v[1].iov_len = oidx; STR2IOVEC(callid, v[3]); STR2IOVEC(newip, v[5]); STR2IOVEC(oldport, v[7]); STR2IOVEC(from_tag, v[9]); if (1 || media_multi) /* XXX netch: can't choose now*/ { snprintf(medianum_buf, sizeof medianum_buf, "%d", medianum); medianum_str.s = medianum_buf; medianum_str.len = strlen(medianum_buf); STR2IOVEC(medianum_str, v[11]); STR2IOVEC(medianum_str, v[15]); } else { v[10].iov_len = v[11].iov_len = 0; v[14].iov_len = v[15].iov_len = 0; } STR2IOVEC(to_tag, v[13]); do { node = select_rtpp_node(callid, 1); if (!node) { LOG(L_ERR, "ERROR: force_rtp_proxy2: no available " "proxies\n"); return -1; } cp = send_rtpp_command(node, v, (to_tag.len > 0) ? 16 : 12); } while (cp == NULL); LOG(L_DBG, "force_rtp_proxy2: proxy reply: %s\n", cp); /* Parse proxy reply to <argc,argv> */ argc = 0; memset(argv, 0, sizeof(argv)); cpend=cp+strlen(cp); next=eat_token_end(cp, cpend); for (ap=argv; cp<cpend; cp=next+1, next=eat_token_end(cp, cpend)){ *next=0; if (*cp != '\0') { *ap=cp; argc++; if ((char*)++ap >= ((char*)argv+sizeof(argv))) break; } } if (argc < 1) { LOG(L_ERR, "force_rtp_proxy2: no reply from rtp proxy\n"); return -1; } port = atoi(argv[0]); if (port <= 0 || port > 65535) { LOG(L_ERR, "force_rtp_proxy2: incorrect port %i in reply " "from rtp proxy\n",port); return -1; } pf1 = (argc >= 3 && argv[2][0] == '6') ? AF_INET6 : AF_INET; if (isnulladdr(&oldip, pf)) { if (pf1 == AF_INET6) { newip.s = "::"; newip.len = 2; } else { newip.s = "0.0.0.0"; newip.len = 7; } } else { newip.s = (argc < 2) ? str2 : argv[1]; newip.len = strlen(newip.s); } newport.s = int2str(port, &newport.len); /* beware static buffer */ /* Alter port. */ body1.s = m1p; body1.len = bodylimit - body1.s; if (alter_mediaport(msg, &body1, &oldport, &newport, 0) == -1) return -1; /* * Alter IP. Don't alter IP common for the session * more than once. */ if (c2p != NULL || !c1p_altered) { body1.s = c2p ? c2p : c1p; body1.len = bodylimit - body1.s; if (alter_mediaip(msg, &body1, &oldip, pf, &newip, pf1, 0)==-1) return -1; if (!c2p) c1p_altered = 1; } /* * Alter common IP if required, but don't do it more than once. */ if (commip && c1p && !c1p_altered) { tmpstr1.s = c1p; tmpstr1.len = v2p - tmpstr1.s; if (extract_mediaip(&tmpstr1, &oldip, &pf,"c=") == -1) { LOG(L_ERR, "ERROR: force_rtp_proxy2: can't" " extract media IP from the message\n"); return -1; } body1.s = c1p; body1.len = bodylimit - body1.s; if (alter_mediaip(msg, &body1, &oldip, pf, &newip, pf1, 0)==-1) return -1; c1p_altered = 1; } /* * Alter the IP in "o=", but only once per session */ if (o1p) { tmpstr1.s = o1p; tmpstr1.len = v2p - tmpstr1.s; if (extract_mediaip(&tmpstr1, &oldip, &pf,"o=") == -1) { LOG(L_ERR, "ERROR: force_rtp_proxy2: can't" " extract media IP from the message\n"); return -1; } body1.s = o1p; body1.len = bodylimit - body1.s; if (alter_mediaip(msg, &body1, &oldip, pf, &newip, pf1, 0)==-1) return -1; o1p = 0; } } /* Iterate medias in session */ } /* Iterate sessions */ if (proxied == 0) { cp = pkg_malloc(ANORTPPROXY_LEN * sizeof(char)); if (cp == NULL) { LOG(L_ERR, "ERROR: force_rtp_proxy2: out of memory\n"); return -1; } anchor = anchor_lump(msg, body.s + body.len - msg->buf, 0, 0); if (anchor == NULL) { LOG(L_ERR, "ERROR: force_rtp_proxy2: anchor_lump failed\n"); pkg_free(cp); return -1; } memcpy(cp, ANORTPPROXY, ANORTPPROXY_LEN); if (insert_new_lump_after(anchor, cp, ANORTPPROXY_LEN, 0) == NULL) { LOG(L_ERR, "ERROR: force_rtp_proxy2: insert_new_lump_after failed\n"); pkg_free(cp); return -1; } } return 1;}static intforce_rtp_proxy1_f(struct sip_msg* msg, char* str1, char* str2){ char *cp; char newip[IP_ADDR_MAX_STR_SIZE]; cp = ip_addr2a(&msg->rcv.dst_ip); strcpy(newip, cp); return force_rtp_proxy2_f(msg, str1, newip);}static intforce_rtp_proxy0_f(struct sip_msg* msg, char* str1, char* str2){ char arg[1] = {'\0'}; return force_rtp_proxy1_f(msg, arg, NULL);}static voidnh_timer(unsigned int ticks, void *param){ int rval; void *buf, *cp; str c; struct sip_uri curi; union sockaddr_union to; struct hostent* he; struct socket_info* send_sock; unsigned int flags; int proto; str opt; buf = NULL; if (cblen > 0) { buf = pkg_malloc(cblen); if (buf == NULL) { LOG(L_ERR, "ERROR:nathelper:nh_timer: out of memory\n"); return; } } rval = ul.get_all_ucontacts(buf, cblen, (ping_nated_only ? FL_NAT : 0)); if (rval > 0) { if (buf != NULL) pkg_free(buf); cblen = rval * 2; buf = pkg_malloc(cblen); if (buf == NULL) { LOG(L_ERR, "ERROR:nathelper:nh_timer: out of memory\n"); return; } rval = ul.get_all_ucontacts(buf, cblen, (ping_nated_only ? FL_NAT : 0)); if (rval != 0) { pkg_free(buf); return; } } if (buf == NULL) return; cp = buf; while (1) { memcpy(&(c.len), cp, sizeof(c.len)); if (c.len == 0) break; c.s = (char*)cp + sizeof(c.len); cp = (char*)cp + sizeof(c.len) + c.len; memcpy( &send_sock, cp, sizeof(send_sock)); cp += sizeof(send_sock); memcpy( &flags, cp, sizeof(flags)); cp += sizeof(flags); if (parse_uri(c.s, c.len, &curi) < 0) { LOG(L_ERR, "ERROR:nathelper:nh_timer: can't parse contact uri\n"); continue; } if (curi.proto != PROTO_UDP && curi.proto != PROTO_NONE) continue; if (curi.port_no == 0) curi.port_no = SIP_PORT; proto = curi.proto; /* we sholud get rid of this resolve (to ofen and to slow); for the * moment we are lucky since the curi is an IP -bogdan */ he = sip_resolvehost(&curi.host, &curi.port_no, &proto, 0); if (he == NULL){ LOG(L_ERR, "ERROR:nathelper:nh_timer: can't resolve_host\n"); continue; } hostent2su(&to, he, 0, curi.port_no); if (send_sock==0) { send_sock=force_socket ? force_socket : get_send_socket(0, &to, PROTO_UDP); } if (send_sock == NULL) { LOG(L_ERR, "ERROR:nathelper:nh_timer: can't get sending socket\n"); continue; } if ( (sipping_from.s!=0) && (flags&FL_NAT_SIPPING)!=0 && (opt.s=build_sipping( &c, send_sock, &opt.len))!=0 ) { if (udp_send(send_sock, opt.s, opt.len, &to)<0){ LOG(L_ERR, "ERROR:nathelper:nh_timer: sip udp_send failed\n"); } } else { if (udp_send(send_sock, (char *)sbuf, sizeof(sbuf), &to)<0 ) { LOG(L_ERR, "ERROR:nathelper:nh_timer: udp udp_send failed\n"); } } } pkg_free(buf);}/* * Create received SIP uri that will be either * passed to registrar in an AVP or apended * to Contact header field as a parameter */static intcreate_rcv_uri(str* uri, struct sip_msg* m){ static char buf[MAX_URI_SIZE]; char* p; str ip, port; int len; str proto; if (!uri || !m) { LOG(L_ERR, "create_rcv_uri: Invalid parameter value\n"); return -1; } ip.s = ip_addr2a(&m->rcv.src_ip); ip.len = strlen(ip.s); port.s = int2str(m->rcv.src_port, &port.len); switch(m->rcv.proto) { case PROTO_NONE: case PROTO_UDP: proto.s = 0; /* Do not add transport parameter, UDP is default */ proto.len = 0; break; case PROTO_TCP: proto.s = "TCP"; proto.len = 3; break; case PROTO_TLS: proto.s = "TLS"; proto.len = 3; break; case PROTO_SCTP: proto.s = "SCTP"; proto.len = 4; break; default: LOG(L_ERR, "BUG: create_rcv_uri: Unknown transport protocol\n"); return -1; } len = 4 + ip.len + 2*(m->rcv.src_ip.af==AF_INET6)+ 1 + port.len; if (proto.s) { len += TRANSPORT_PARAM_LEN; len += proto.len; } if (len > MAX_URI_SIZE) { LOG(L_ERR, "create_rcv_uri: Buffer too small\n"); return -1; } p = buf; memcpy(p, "sip:", 4); p += 4; if (m->rcv.src_ip.af==AF_INET6) *p++ = '['; memcpy(p, ip.s, ip.len); p += ip.len; if (m->rcv.src_ip.af==AF_INET6) *p++ = ']'; *p++ = ':'; memcpy(p, port.s, port.len); p += port.len; if (proto.s) { memcpy(p, TRANSPORT_PARAM, TRANSPORT_PARAM_LEN); p += TRANSPORT_PARAM_LEN; memcpy(p, proto.s, proto.len); p += proto.len; } uri->s = buf; uri->len = len; return 0;}/* * Add received parameter to Contacts for further * forwarding of the REGISTER requuest */static intadd_rcv_param_f(struct sip_msg* msg, char* str1, char* str2){ contact_t* c; struct lump* anchor; char* param; str uri; int hdr_param; hdr_param = str1?0:1; if (create_rcv_uri(&uri, msg) < 0) { return -1; } if (contact_iterator(&c, msg, 0) < 0) { return -1; } while(c) { param = (char*)pkg_malloc(RECEIVED_LEN + 2 + uri.len); if (!param) { LOG(L_ERR, "add_rcv_param: No memory left\n"); return -1; } memcpy(param, RECEIVED, RECEIVED_LEN); param[RECEIVED_LEN] = '\"'; memcpy(param + RECEIVED_LEN + 1, uri.s, uri.len); param[RECEIVED_LEN + 1 + uri.len] = '\"'; if (hdr_param) { /* add the param as header param */ anchor = anchor_lump(msg, c->name.s + c->len - msg->buf, 0, 0); } else { /* add the param as uri param */ anchor = anchor_lump(msg, c->uri.s + c->uri.len - msg->buf, 0, 0); } if (anchor == NULL) { LOG(L_ERR, "add_rcv_param: anchor_lump failed\n"); return -1; } if (insert_new_lump_after(anchor, param, RECEIVED_LEN + 1 + uri.len + 1, 0) == 0) { LOG(L_ERR, "add_rcv_param: insert_new_lump_after failed\n"); pkg_free(param); return -1; } if (contact_iterator(&c, msg, c) < 0) { return -1; } } return 1;}/* * Create an AVP to be used by registrar with the source IP and port * of the REGISTER */static intfix_nated_register_f(struct sip_msg* msg, char* str1, char* str2){ str uri; int_str val; int_str rcv_avp; if (create_rcv_uri(&uri, msg) < 0) { return -1; } val.s = uri; rcv_avp.n=rcv_avp_no; if (add_avp(AVP_VAL_STR, rcv_avp, val) < 0) { LOG(L_ERR, "fix_nated_register: Error while creating AVP\n"); return -1; } return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -