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

📄 save.c

📁 性能优秀的SIP Proxy
💻 C
📖 第 1 页 / 共 2 页
字号:
		calc_contact_expires(_m, _c->expires, &e);		/* Skip contacts with zero expires */		if (e == 0)			continue;		if (max_contacts && (num >= max_contacts)) {			LOG(L_INFO,"INFO:registrar:insert_contacts: too many contacts "				"(%d) for AOR <%.*s>\n", num, _a->len, _a->s);			rerrno = R_TOO_MANY;			goto error;		}		num++;		if (r==0) {			if (ul.insert_urecord(_d, _a, &r) < 0) {				rerrno = R_UL_NEW_R;				LOG(L_ERR, "ERROR:registrar:insert_contacts: failed to insert "					"new record structure\n");				goto error;			}		}		/* pack the contact_info */		if ( (ci=pack_ci( (ci==0)?_m:0, _c, e, flags, 0))==0 ) {			LOG(L_ERR, "ERROR:registrar:insert_contacts: failed to extract "				"contact info\n");			goto error;		}		if ( r->contacts==0 ||		ul.get_ucontact(r, &_c->uri, ci->callid, ci->cseq+1, &c)!=0 ) {			if (ul.insert_ucontact( r, &_c->uri, ci, &c) < 0) {				rerrno = R_UL_INS_C;				LOG(L_ERR, "ERROR:registrar:insert_contacts: failed to insert "					"contact\n");				goto error;			}		} else {			if (ul.update_ucontact( c, ci) < 0) {				rerrno = R_UL_UPD_C;				LOG(L_ERR, "ERROR:registrar:insert_contacts: failed to update "					"contact\n");				goto error;			}		}#ifdef USE_TCP		if (tcp_check) {			/* parse contact uri to see if transport is TCP */			if (parse_uri( _c->uri.s, _c->uri.len, &uri)<0) {				LOG(L_ERR,"ERROR:registrar:insert_contacts failed to parse "					"contact <%.*s>\n", _c->uri.len, _c->uri.s);			} else if (uri.proto==PROTO_TCP || uri.proto==PROTO_TLS) {				if (e_max) {					LOG(L_WARN,"WARNING:registrar:insert_contacts: multiple "						"TCP contacts on single REGISTER\n");					if (e>e_max) e_max = e;				} else {					e_max = e;				}			}		}#endif	}	if (r) {		if (r->contacts)			build_contact(r->contacts);		ul.release_urecord(r);	}#ifdef USE_TCP	if ( tcp_check && e_max>0 ) {		e_max -= act_time;		force_tcp_conn_lifetime( &_m->rcv , e_max + 10 );	}#endif	return 0;error:	if (r)		ul.delete_urecord(_d, _a, r);	return -1;}static int test_max_contacts(struct sip_msg* _m, urecord_t* _r, contact_t* _c,														ucontact_info_t *ci){	int num;	int e;	ucontact_t* ptr, *cont;	int ret;		num = 0;	ptr = _r->contacts;	while(ptr) {		if (VALID_CONTACT(ptr, act_time)) {			num++;		}		ptr = ptr->next;	}	DBG("DEBUG:registrar:test_max_contacts: %d valid contacts\n", num);		for( ; _c ; _c = get_next_contact(_c) ) {		/* calculate expires */		calc_contact_expires(_m, _c->expires, &e);				ret = ul.get_ucontact( _r, &_c->uri, ci->callid, ci->cseq, &cont);		if (ret==-1) {			LOG(L_ERR,"ERROR:registrar:update_contacts: invalid cseq for aor "				"<%.*s>\n",_r->aor.len,_r->aor.s);			rerrno = R_INV_CSEQ;			return -1;		} else if (ret==-2) {			continue;		}		if (ret > 0) {			/* Contact not found */			if (e != 0) num++;		} else {			if (e == 0) num--;		}	}		DBG("DEBUG:registrar:test_max_contacts: %d contacts after commit\n", num);	if (num > max_contacts) {		LOG(L_INFO,"INFO:registrar:test_max_contacts: too many contacts "				"for AOR <%.*s>\n", _r->aor.len, _r->aor.s);		rerrno = R_TOO_MANY;		return -1;	}	return 0;}/* * Message contained some contacts and appropriate * record was found, so we have to walk through * all contacts and do the following: * 1) If contact in usrloc doesn't exists and *    expires > 0, insert new contact * 2) If contact in usrloc exists and expires *    > 0, update the contact * 3) If contact in usrloc exists and expires *    == 0, delete contact */static inline int update_contacts(struct sip_msg* _m, urecord_t* _r,																contact_t* _c){	ucontact_info_t *ci;	ucontact_t* c;	int e;	int set, reset;	unsigned int flags;	int ret;#ifdef USE_TCP	int e_max;	int tcp_check;	struct sip_uri uri;#endif	/* is nated flag */	if (_m->flags&nat_flag)		flags = FL_NAT;	else		flags = FL_NONE;	/* nat type flag */	if (_m->flags&sip_natping_flag)		flags |= FL_NAT_SIPPING;	/* pack the contact_info */	if ( (ci=pack_ci( _m, 0, 0, 0, 0))==0 ) {		LOG(L_ERR, "ERROR:registrar:update_contacts: failed to "			"initial pack contact info\n");		goto error;	}	if (max_contacts && test_max_contacts(_m, _r, _c, ci) != 0 )		goto error;#ifdef USE_TCP	if ( (_m->flags&tcp_persistent_flag) &&	(_m->rcv.proto==PROTO_TCP||_m->rcv.proto==PROTO_TLS)) {		e_max = -1;		tcp_check = 1;	} else {		e_max = tcp_check = 0;	}#endif	for( ; _c ; _c = get_next_contact(_c) ) {		/* calculate expires */		calc_contact_expires(_m, _c->expires, &e);		/* search for the contact*/		ret = ul.get_ucontact( _r, &_c->uri, ci->callid, ci->cseq, &c);		if (ret==-1) {			LOG(L_ERR,"ERROR:registrar:update_contacts: invalid cseq for aor "				"<%.*s>\n",_r->aor.len,_r->aor.s);			rerrno = R_INV_CSEQ;			goto error;		} else if (ret==-2) {			continue;		}		if ( ret > 0 ) {			/* Contact not found -> expired? */			if (e==0)				continue;			/* pack the contact_info */			if ( (ci=pack_ci( 0, _c, e, flags, 0))==0 ) {				LOG(L_ERR, "ERROR:registrar:update_contacts: failed to "					"extract contact info\n");				goto error;			}			if (ul.insert_ucontact( _r, &_c->uri, ci, &c) < 0) {				rerrno = R_UL_INS_C;				LOG(L_ERR, "ERROR:registrar:update_contacts: failed to insert "					"contact\n");				goto error;			}		} else {			/* Contact found */			if (e == 0) {				/* it's expired */				if (mem_only) {					c->flags |= FL_MEM;				} else {					c->flags &= ~FL_MEM;				}				if (ul.delete_ucontact(_r, c) < 0) {					rerrno = R_UL_DEL_C;					LOG(L_ERR, "ERROR:registrar:update_contacts: failed "						"to delete contact\n");					goto error;				}			} else {				/* do update */				set = flags | mem_only;				reset = ~(flags | mem_only) & (FL_NAT|FL_MEM|FL_NAT_SIPPING);				/* pack the contact specific info */				if ( (ci=pack_ci( 0, _c, e, set, reset))==0 ) {					LOG(L_ERR, "ERROR:registrar:update_contacts: failed to "						"pack contact specific info\n");					goto error;				}				if (ul.update_ucontact(c, ci) < 0) {					rerrno = R_UL_UPD_C;					LOG(L_ERR, "ERROR:registrar:update_contacts: failed to "						"update contact\n");					goto error;				}				if (desc_time_order) {					move_on_top(_r, c);				}			}		}#ifdef USE_TCP		if (tcp_check) {			/* parse contact uri to see if transport is TCP */			if (parse_uri( _c->uri.s, _c->uri.len, &uri)<0) {				LOG(L_ERR,"ERROR:registrar:update_contacts failed to parse "					"contact <%.*s>\n", _c->uri.len, _c->uri.s);			} else if (uri.proto==PROTO_TCP || uri.proto==PROTO_TLS) {				if (e_max>0) {					LOG(L_WARN,"WARNING:registrar:update_contacts: multiple "						"TCP contacts on single REGISTER\n");				}				if (e>e_max) e_max = e;			}		}#endif		if (e>e_max)			e_max = e;	}#ifdef USE_TCP	if ( tcp_check && e_max>-1 ) {		if (e_max) e_max -= act_time;		force_tcp_conn_lifetime( &_m->rcv , e_max + 10 );	}#endif	return 0;error:	return -1;}/*  * This function will process request that * contained some contact header fields */static inline int add_contacts(struct sip_msg* _m, contact_t* _c,													udomain_t* _d, str* _a){	int res;	urecord_t* r;	ul.lock_udomain(_d);	res = ul.get_urecord(_d, _a, &r);	if (res < 0) {		rerrno = R_UL_GET_R;		LOG(L_ERR, "ERROR:registrar:add_contacts: failed to retrieve record "			"from usrloc\n");		ul.unlock_udomain(_d);		return -2;	}	if (res == 0) { /* Contacts found */		if (update_contacts(_m, r, _c) < 0) {			build_contact(r->contacts);			ul.release_urecord(r);			ul.unlock_udomain(_d);			return -3;		}		build_contact(r->contacts);		ul.release_urecord(r);	} else {		if (insert_contacts(_m, _c, _d, _a) < 0) {			ul.unlock_udomain(_d);			return -4;		}	}	ul.unlock_udomain(_d);	return 0;}/* * Process REGISTER request and save it's contacts */static inline int save_real(struct sip_msg* _m, udomain_t* _t, int doreply){	contact_t* c;	int st;	str aor;	rerrno = R_FINE;	if (parse_message(_m) < 0) {		goto error;	}	if (check_contacts(_m, &st) > 0) {		goto error;	}		get_act_time();	c = get_first_contact(_m);	if (extract_aor(&get_to(_m)->uri, &aor) < 0) {		LOG(L_ERR, "ERROR:registrar:save_real: failed to extract "			"Address Of Record\n");		goto error;	}	if (c == 0) {		if (st) {			if (star(_t, &aor) < 0) goto error;		} else {			if (no_contacts(_t, &aor) < 0) goto error;		}	} else {		if (add_contacts(_m, c, _t, &aor) < 0) goto error;	}	if (doreply && (send_reply(_m) < 0)) return -1;	else return 1;error:	if (doreply) send_reply(_m);	return 0;}/* * Process REGISTER request and save it's contacts */int save(struct sip_msg* _m, char* _t, char* _s){	mem_only = FL_NONE;	return save_real(_m, (udomain_t*)_t, 1);}/* * Process REGISTER request and save it's contacts, do not send any replies */int save_noreply(struct sip_msg* _m, char* _t, char* _s){	mem_only = FL_NONE;	return save_real(_m, (udomain_t*)_t, 0);}/* * Update memory cache only */int save_memory(struct sip_msg* _m, char* _t, char* _s){	mem_only = FL_MEM;	return save_real(_m, (udomain_t*)_t, 1);}

⌨️ 快捷键说明

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