⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nathelper.c

📁 性能优秀的SIP Proxy
💻 C
📖 第 1 页 / 共 5 页
字号:
			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 + -