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

📄 nathelper.c

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