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

📄 loose.c

📁 用来作为linux中SIP SERVER,完成VOIP网络电话中服务器的功能
💻 C
📖 第 1 页 / 共 2 页
字号:
		pkg_free(s);		LOG(L_ERR, "save_ruri: Cannot insert lump\n");		return -4;	}	return 0;}/* * Logic necessary to forward request to strict routers * * Returns 0 on success, negative number on an error */static inline int handle_sr(struct sip_msg* _m, struct hdr_field* _hdr, rr_t* _r){	str* uri;	char* rem_off;	int rem_len;	uri = &_r->nameaddr.uri;	     /* Next hop is strict router, save R-URI here */	if (save_ruri(_m) < 0) {		LOG(L_ERR, "handle_sr: Error while saving Request-URI\n");		return -1;	}		     /* Put the first Route in Request-URI */	if (rewrite_uri(_m, uri) < 0) {		LOG(L_ERR, "handle_sr: Error while rewriting request URI\n");		return -2;	}	if (!_r->next) {		rem_off = _hdr->name.s;		rem_len = _hdr->len;	} else {		rem_off = _hdr->body.s;		rem_len = _r->next->nameaddr.name.s - _hdr->body.s;	}	if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {		LOG(L_ERR, "handle_sr: Can't remove Route HF\n");		return -9;	}				return 0;}/* * Find last route in the last Route header field, * if there was a previous route in the last Route header * field, it will be saved in _p parameter */static inline int find_rem_target(struct sip_msg* _m, struct hdr_field** _h, rr_t** _l, rr_t** _p){	struct hdr_field* ptr, *last;	if (parse_headers(_m, HDR_EOH, 0) == -1) {		LOG(L_ERR, "find_rem_target: Error while parsing message header\n");		return -1;	}	ptr = _m->route;	last = 0;	while(ptr) {		if (ptr->type == HDR_ROUTE) last = ptr;		ptr = ptr->next;	}	if (last) {		if (parse_rr(last) < 0) {			LOG(L_ERR, "find_rem_target: Error while parsing last Route HF\n");			return -2;		}		*_p = 0;		*_l = (rr_t*)last->parsed;		while ((*_l)->next) {			*_p = *_l;			*_l = (*_l)->next;		}		return 0;	} else {		LOG(L_ERR, "find_rem_target: Can't find last Route HF\n");		return 1;	}}/* * Previous hop was a strict router, handle this case */static inline int after_strict(struct sip_msg* _m){	int res, rem_len;	struct hdr_field* hdr;	struct sip_uri puri;	rr_t* rt, *prev;	char* rem_off;	str* uri;	hdr = _m->route;	rt = (rr_t*)hdr->parsed;	uri = &rt->nameaddr.uri;	if (parse_uri(uri->s, uri->len, &puri) < 0) {		LOG(L_ERR, "after_strict: Error while parsing the first route URI\n");		return RR_ERROR;	}#ifdef ENABLE_USER_CHECK	if (is_myself(&puri.user, &puri.host, puri.port_no))#else	if (is_myself(&puri.host, puri.port_no))#endif	{		     /*	if (enable_double_rr && is_2rr(&_ruri->params)) { */ 	      /* DBG("ras(): Removing 2nd URI of mine: '%.*s'\n", rt->nameaddr.uri.len, ZSW(rt->nameaddr.uri.s)); */ 		if (!rt->next) {			     /* No next route in the same header, remove the whole header			      * field immediately			      */			if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {				LOG(L_ERR, "after_strict: Cannot remove Route HF\n");				return RR_ERROR;			}			res = find_next_route(_m, &hdr);			if (res < 0) {				LOG(L_ERR, "after_strict: Error while searching next route\n");				return RR_ERROR;			}			if (res > 0) { /* No next route found */				DBG("after_strict: No next URI found\n");				return NOT_RR_DRIVEN;			}			rt = (rr_t*)hdr->parsed;		} else rt = rt->next;	}	uri = &rt->nameaddr.uri;	if (parse_uri(uri->s, uri->len, &puri) == -1) {		LOG(L_ERR, "after_strict: Error while parsing URI\n");		return RR_ERROR;	}	if (is_strict(&puri.params)) {		DBG("after_strict: Next hop: '%.*s' is strict router\n", uri->len, ZSW(uri->s));		     /* Previous hop was a strict router and the next hop is strict		      * router too. There is no need to save R-URI again because it		      * is saved already. In fact, in this case we will behave exactly		      * like a strict router.		      */		     /* Note: when there is only one Route URI left (endpoint), it will		      * always be a strict router because endpoints don't use ;lr parameter		      * In this case we will simply put the URI in R-URI and forward it, which		      * will work perfectly		      */		if (rewrite_uri(_m, uri) < 0) {			LOG(L_ERR, "after_strict: Error while rewriting request URI\n");			return RR_ERROR;		}				if (rt->next) {			rem_off = hdr->body.s;			rem_len = rt->next->nameaddr.name.s - hdr->body.s;		} else {			rem_off = hdr->name.s;			rem_len = hdr->len;		}		if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {			LOG(L_ERR, "after_strict: Cannot remove Route HF\n");			return RR_ERROR;		}	} else {		DBG("after_strict: Next hop: '%.*s' is loose router\n", uri->len, ZSW(uri->s));		if (set_dst_uri(_m, uri) < 0) {			LOG(L_ERR, "after_strict: Error while setting dst_uri\n");			return RR_ERROR;		}		     /* Next hop is a loose router - Which means that is is not endpoint yet		      * In This case we have to recover from previous strict routing, that 		      * means we have to find the last Route URI and put in in R-URI and 		      * remove the last Route URI.		      */		if (rt != hdr->parsed) {			     /* There is a previous route uri which was 2nd uri of mine			      * and must be removed here			      */			rem_off = hdr->body.s;			rem_len = rt->nameaddr.name.s - hdr->body.s;			if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {				LOG(L_ERR, "after_strict: Can't remove Route HF\n");				return RR_ERROR;			}					}		res = find_rem_target(_m, &hdr, &rt, &prev);		if (res < 0) {			LOG(L_ERR, "after_strict: Error while looking for last Route URI\n");			return RR_ERROR;		} else if (res > 0) {			     /* No remote target is an error */			return RR_ERROR;		}		uri = &rt->nameaddr.uri;		if (rewrite_uri(_m, uri) < 0) {			LOG(L_ERR, "after_strict: Can't rewrite R-URI\n");			return RR_ERROR;		}				     /* The first character if uri will be either '<' when it is the only URI in a		      * Route header field or ',' if there is more than one URI in the header field		      */		DBG("after_strict: The last route URI: '%.*s'\n", 		    rt->nameaddr.uri.len, ZSW(rt->nameaddr.uri.s));		if (prev) {			rem_off = prev->nameaddr.name.s + prev->len;			rem_len = rt->nameaddr.name.s + rt->len - rem_off;		} else {			rem_off = hdr->name.s;			rem_len = hdr->len;		}		if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {			LOG(L_ERR, "after_strict: Can't remove Route HF\n");			return RR_ERROR;		}	}		return RR_DRIVEN;}static inline int after_loose(struct sip_msg* _m, int preloaded){	struct hdr_field* hdr;	struct sip_uri puri;	rr_t* rt;	int res;	#ifdef ENABLE_USER_CHECK	int ret;#endif	str* uri;	hdr = _m->route;	rt = (rr_t*)hdr->parsed;	uri = &rt->nameaddr.uri;	if (parse_uri(uri->s, uri->len, &puri) < 0) {		LOG(L_ERR, "after_loose: Error while parsing the first route URI\n");		return RR_ERROR;	}	     /* IF the URI was added by me, remove it */#ifdef ENABLE_USER_CHECK	ret=is_myself(&puri.user, &puri.host, puri.port_no);	if (ret>0)#else	if (is_myself(&puri.host, puri.port_no))#endif	{		DBG("after_loose: Topmost route URI: '%.*s' is me\n", uri->len, ZSW(uri->s));		if (!rt->next) {			     /* No next route in the same header, remove the whole header			      * field immediately			      */			if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {				LOG(L_ERR, "after_loose: Can't remove Route HF\n");				return RR_ERROR;			}			res = find_next_route(_m, &hdr);			if (res < 0) {				LOG(L_ERR, "after_loose: Error while finding next route\n");				return RR_ERROR;			}			if (res > 0) { /* No next route found */				DBG("after_loose: No next URI found\n");				return (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN);			}			rt = (rr_t*)hdr->parsed;		} else rt = rt->next;				if (enable_double_rr && is_2rr(&puri.params)) {			if (!rt->next) {				     /* No next route in the same header, remove the whole header				      * field immediately				      */				if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {					LOG(L_ERR, "after_loose: Can't remove Route HF\n");					return RR_ERROR;				}				res = find_next_route(_m, &hdr);				if (res < 0) {					LOG(L_ERR, "after_loose: Error while finding next route\n");					return RR_ERROR;				}				if (res > 0) { /* No next route found */					DBG("after_loose: No next URI found\n");					return (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN);				}				rt = (rr_t*)hdr->parsed;			} else rt = rt->next;		}				uri = &rt->nameaddr.uri;		if (parse_uri(uri->s, uri->len, &puri) < 0) {			LOG(L_ERR, "after_loose: Error while parsing the first route URI\n");			return RR_ERROR;		}	} else {#ifdef ENABLE_USER_CHECK		/* check if it the ignored user */		if(ret < 0)			return NOT_RR_DRIVEN;#endif			DBG("after_loose: Topmost URI is NOT myself\n");	}		DBG("after_loose: URI to be processed: '%.*s'\n", uri->len, ZSW(uri->s));	if (is_strict(&puri.params)) {		DBG("after_loose: Next URI is a strict router\n");		if (handle_sr(_m, hdr, rt) < 0) {			LOG(L_ERR, "after_loose: Error while handling strict router\n");			return RR_ERROR;		}	} else {		     /* Next hop is loose router */		DBG("after_loose: Next URI is a loose router\n");		if (set_dst_uri(_m, uri) < 0) {			LOG(L_ERR, "after_loose: Error while setting dst_uri\n");			return RR_ERROR;		}		     /* There is a previous route uri which was 2nd uri of mine		      * and must be removed here		      */		if (rt != hdr->parsed) {			if (!del_lump(_m, hdr->body.s - _m->buf, rt->nameaddr.name.s - hdr->body.s, 0)) {				LOG(L_ERR, "after_loose: Can't remove Route HF\n");				return RR_ERROR;			}					}	}	return RR_DRIVEN;}/* * Do loose routing as defined in RFC3621 */int loose_route(struct sip_msg* _m, char* _s1, char* _s2){	int ret;	if (find_first_route(_m) != 0) {		DBG("loose_route: There is no Route HF\n");		return -1;	}			if (parse_sip_msg_uri(_m) == -1) {		LOG(L_ERR, "loose_route: Error while parsing Request URI\n");		return -1;	}	ret = is_preloaded(_m);	if (ret < 0) {		return -1;	} else if (ret == 1) {		return after_loose(_m, 1);	} else {#ifdef ENABLE_USER_CHECK		if (is_myself(&_m->parsed_uri, &_m->parsed_uri.host, &_m->parsed_uri.port_no)) {#else		if (is_myself(&_m->parsed_uri.host, _m->parsed_uri.port_no)) {#endif			return after_strict(_m);		} else {			return after_loose(_m, 0);		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -